私の質問は、別のクラスを拡張するクラスを作成できますが、特定のメソッドを継承しないことを選択できますか?
簡単な例として、fly()という1つのメソッドを持つ抽象Birdクラスがあります。さまざまな種類の鳥のクラスを作成したいのですが、ペンギンは飛べません。ペンギンオブジェクトがfly()メソッドを呼び出せないようにするにはどうすればよいですか?
私の質問は、別のクラスを拡張するクラスを作成できますが、特定のメソッドを継承しないことを選択できますか?
簡単な例として、fly()という1つのメソッドを持つ抽象Birdクラスがあります。さまざまな種類の鳥のクラスを作成したいのですが、ペンギンは飛べません。ペンギンオブジェクトがfly()メソッドを呼び出せないようにするにはどうすればよいですか?
いいえ、できません
最も近い方法は、メソッドをオーバーライドしてスローすることです
@Override
public void fly() {
throw new UnsuportedOperationException();
}
Java API は時々これを行いますが、これは個人的に悪い設計だと思います。
できることは、Bird の階層と FlyableBird および NonFlyableBird の 2 つのサブクラスを作成し、Penguin を NonFlyableBird から切り離すことです。fly メソッドは FlyableBird クラスにのみ存在します。鳥のクラスには、FlyableBird と NonFlyableBird の両方に共通する makeNoise() (すべての鳥は音を立てますよね?) などを含めることができます。
いいえ、できません。それはポリモーフィズムを根本的に壊してしまいます。関数を実装して、例外をスローするか、何もしないなどの操作を行う必要があります。
あなたが言及したシナリオを実装するには、非常に優れた設計が必要です。以下のような設計が必要です。
public abstract class Bird {
FlyBehavior flyBehavior;
public Bird(){
}
public void performFly(){
flyBehavior.fly();
}
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
}
public interface FlyBehavior {
public void fly();
}
public class FlyingBirds implements FlyBehavior {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("I can fly");
}
}
public class NonFlyingBirds implements FlyBehavior {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("I am not able to fly");
}
}
public class KingFisher extends Bird {
public KingFisher(){
flyBehavior = new FlyingBirds();
}
public static void main(String[] args) {
Bird bird = new KingFisher();
bird.performFly();
}
}
public class Penguins extends Bird {
public Penguins(){
flyBehavior = new NonFlyingBirds();
}
public static void main(String[] args) {
Bird bird = new Penguins();
bird.performFly();
}
}
できません。UnsupportedOperationException
しかし、あなたはペンギンのfly()
方法で投げることができます。
やろうとしていることをする必要がある場合、クラス/概念の階層が間違っています。クラスを再設計します。
fly、walk などの抽象メソッドを使用して、1 つのメイン抽象クラス Bird を作成できます。次に、その Bird クラスの 2 つのサブクラスを作成できます。FlyingBirds と NonFlyingBirds.飛べない鳥の具体的なクラスでは、fly メソッドを final にすることができます。そのため、このメソッドはサブクラスに継承されません。
fly メソッドをオーバーライドして、別のアクションを指すか、そのアクションを実行せずに戻ります。
メソッド Fly を抽象メソッドとして宣言することもできますが、実装を提供しない場合は、ペンギン クラスも抽象として宣言する必要があります。抽象的で、意味がありません。