2014-10-19 1 views
1

Я работаю над заданием, которое включает абстрактный класс, который представляет собой общее животное с подклассами для кошки, собаки, рептилии и т. Д. Суперкласс имеет абстрактные методы , которые фактически не используются каждым подклассом. Например, существуют аксессоры и мутаторы для породы и пола, которые используются собакой и кошкой, но не являются классом рептилий. Я лично считаю, что это странная настройка, но это то, что требуется заданием.Работайте над необходимостью переопределять абстрактные методы в Java?

Сначала я попытался оставить абстрактные методы, не используемые в конкретном подклассе, но я быстро обнаружил, что приводит к ошибке из-за того, что абстрактные методы не переопределяются. Все, что я должен был сделать, чтобы исправить это было положить в соответствующих методах ...

public class Reptile extends Animal 
... 
public void setBreed(String newBreed){} 
public String getBreed(){return null;} 


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

+0

Почему нет реализации по умолчанию для некоторых из добытчиками и сеттеров? Абстрактным классам не нужно, чтобы все методы были абстрактными. (Хотя это может не относиться к вашему конкретному случаю) – Pokechu22

+0

В зависимости от вашего использования интерфейсы могут быть более уместными. Поскольку вы можете реализовать несколько интерфейсов для лучшего определения своего класса. Хотя я не уверен, что это будет разрешено для вашего задания. – Justin

+0

У меня не может быть реализации по умолчанию, потому что назначение специально требует, чтобы я использовал абстрактный метод для методов, которые привели к моему сообщению, хотя это или интерфейсы были бы гораздо более подходящими. – player3

ответ

3

У вас есть два решения здесь.

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

public abstract class Animal{ 
    public abstract void fooMethod(); 
} 

public abstract class Pet extends Animal{ 
    public abstract void breed(); 
    public abstract void gender(); 
} 

public class Reptile extends Animal{ 
    public void fooMethod(){} 
} 
public class Cat extends Pet{ //do the same for Dog 
    public void fooMethod(){} 
    public void breed(){} 
    public void gender(){} 
} 

Этого путь, Рептилии еще продолжаются животные, но вы знаете, Рептилия не имеет породы или гендерную функцию, так что вы дон «Мне нужно что-то сделать для этого. Аналогичным образом, Cat и Dog также распространяют Animal, но теперь у них есть породы и пол, они также должны переопределить.

Ваше другое решение сделать что-то вроде этого (тем хуже двух решений):

public class Reptile extends Animal{ 
    public void breed(){ 
    throw new UnsupportedOperationException("Don't call Reptile#breed!!"); 
    } 
} 

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

Я рекомендую выбор A, лично.

+0

Хорошие примеры. Еще одним вариантом было бы использование интерфейсов. – Justin

+0

в моем конкретном примере, да, вы могли бы использовать интерфейсы. Но если у него есть некоторые функции в Animal (например, fooMethod не абстрактно), то он, очевидно, не мог. – searchengine27

+0

Хорошая точка. К счастью, в большинстве случаев у вас есть возможность перестроить ваш код, чтобы разрешить использование интерфейсов.Особенно с превосходными реализациями по умолчанию, добавленными в Java8 – Justin

1

Другой вариант ответа @ earchengine, добавьте пару интерфейсов:

public abstract class Animal{ 
    public abstract void fooMethod(); 
} 

public class Breed {...} 
public interface Bred { 
    Breed breed(); 
} 

enum Gender { ...} 

public interface Gendered 
    Gender gender(); 
} 

public class Reptile extends Animal { 
    public void fooMethod(){} 
} 

public class Cat extends Animal implements Gendered, Bred { 
    public void fooMethod(){} 
    public Breed breed(){} 
    public Gender gender(){} 
} 

public class Dog extends Animal implements Gendered, Bred { 
    public void fooMethod(){} 
    public Breed breed(){} 
    public Gender gender(){} 
}