2016-08-07 2 views
1

Хорошо, я хочу начать свой вопрос с примера того, что я хотел бы сделать, хотя он не работает таким образом.Шаблон проектирования, необходимый для обеспечения статических методов

Я хочу иметь интерфейс IDog, который применяет его реализации к некоторым методам. Я также хочу суперкласс AbstractDog implements IDog, чтобы дать основные атрибуты и методы всем классам Dog. Тогда я хочу иметь подклассы вроде Poodle extends AbstractDog. Моя проблема здесь static методов - я в основном хочу, чтобы каждый подкласс AbstractDog имел другой метод static, но я хочу, чтобы этот способ применялся с IDog.

Так что моя наивная (и неправильно) реализация будет:

public interface IDog { 

    String getName(); // every dog instance should be able to call name 
    static String getDescription(); // every dog class should be able to get its description 

} 

public abstract class AbstractDog implements IDog { 

    private String name; // every dog instance will have this 

    public AbstractDog(String name) { 
     this.name = name; 
    } 

    @Override 
    public String getName() { 
     return this.name; // every dog instance can call this 
    } 

} 

public class Poodle extends AbstractDog { 

    private static String description = "It's a poodle!"; // all Poodles have the same description 

    public Poodle(String name) { 
     super(name); 
    } 

    @Override // from IDog 
    public static String getDescription() { 
     return description; 
    } 

} 

Теперь, как я уже сказал, это не правильно, потому что AbstractDog классу будет нужен static abstract метод getDescription() и IDog нуждается в реализации своего метода и его нельзя переопределить.

Я хочу знать, если есть шаблон проектирования, который соответствует моей проблеме: применение набора классов (которые могут или должны иметь промежуточный суперкласс) для реализации статического метода (другого!).

Одним из возможных вариантов я обнаружил, но я не уверен, что это может быть полезно или даже адекватной, было бы использование enum DogType, а затем просто имея class Dog с DogType атрибута:

public enum DogType { 

    Poodle("This is a poodle."), Havanese("This is a Havanese.)"; 

    private String description; 

    private DogType(String description) { 
     this.description = description; 
    } 

    public String getDescription() { 
     return this.description; 
    } 
} 

public class Dog { 

    private String name; 
    private DogType dogType; 

    public Dog(String name, DogType dogType) { 
     this.name = name; 
     this.dogType = dogType; 
    } 

    public String getName() { 
     return this.name; 
    } 

    public String getDescription { 
     return this.dogType.getDescription(); 
    } 
} 

Однако этот «обходной путь» теряет способность по моей первоначальной идее: теперь я не могу добавлять дополнительные функциональные возможности только к одному классу собак, например, к методу экземпляра void prance(), который должен быть доступен только для Poodle.

Многие темы, относящиеся к подобным вопросам, относятся к шаблону Factory, но я не уверен, как он подходит для моей проблемы, потому что мне не обязательно нужен метод построения. И по мере того, как растет количество собак, мой код будет очень запутанным, я думаю. Или, может быть, я просто не понял, как Фабрика должна быть правильно использована в моем случае.

+0

'public String getDescription() { возвращение« Это пудель! »; } '??? – fabian

ответ

2

Это запах кода, вероятно, лучший способ это сделать.

Если статический метод всегда возвращает одно и то же для всех объектов класса, вы должны просто сделать его регулярным методом get.

@Override \\ from IDog 
public String getDescription() { 
    return "This is a poodle"; 
} 

Если статическая переменная может быть изменена затем создать новый объект, который держит этот класс в масштабах государства и дать его каждому классу в конструкторе.

ex.

// StringState is a new class that holds a string and has a set and get method 
StringState desc = new StringState("original description"); 
IDog dog1 = new Poodle(desc); 
IDog dog2 = new Poodle(desc); 
// prints original description 
System.out.Println(dog1.getDescription()); 
System.out.Println(dog2.getDescription()); 

desc.set("New description"); 
// prints new description, since both objects share the same 
// StringState,changing it here changes it in all of them. 
System.out.Println(dog1.getDescription()); 
System.out.Println(dog2.getDescription()); 
+0

С этой реализацией я теряю возможность вызывать 'Poodle.getDescription()'. Возможность получить описание должна быть независимой от любых экземпляров «Пуделя». (И теперь я вижу, что мой пример был плохим, в описании должно было быть указано что-то вроде «Пудели - это своего рода собака. Blah blah.») – Paul

3

Интерфейсы являются принудительным поведением. Классы используются для указания свойств. Статические методы скрываются. Они не перегружены подклассами. Поэтому, если у вас есть статические методы в ваших подклассах, но ссылка на объект имеет класс супертипа, тогда вызывается ваш статический метод из суперкласса. Это метод Метод скрывается, происходит со статическими методами.

Я хочу знать, если есть шаблон дизайна, который соответствует моей проблеме: исполнение набора классов (которые могут или должны иметь промежуточный суперкласс) для реализации (другое!) Статического метода.

Извините. Статические методы и наследование не идут рука об руку.

теперь я не могу дополнительные функциональные возможности только один класс собак, как метод экземпляра ничтожной гарцевать(), который должен быть доступен только для пудель.

Вы можете ввести интерфейс Prancable способом void prance().

public interface Prancable{ 
     void prance(); 
} 
public class Poodle extends Dog implements Prancable{ 
     @Override 
     public void prance(){ 
      System.out.println("My Poodle can prance."); 
     } 
} 

Вы можете действовать таким образом для определенных методов, которые добавляют поведение к разным породам собак.

+0

Ваш пример в конце предназначен для использования с enum DogType, как I определил? Тогда у меня должен быть класс 'Poodle' с (унаследованным) атрибутом' DogType dogType' и конструктором 'Poodle (String name)', который вызывает 'super (name, DogType.Poodle)' - правильно? Но разве это не избыток? – Paul

+0

Наличие унаследованного 'enum DogType' из супертипа' Dog' в порядке. Вы можете использовать «DogType» для генерации различных типов собак из «DogFactory». –

+0

Не могли бы вы объяснить это дальше? – Paul

 Смежные вопросы

  • Нет связанных вопросов^_^