一个扩展类不能继承一个方法吗?

5

我的问题是:我能创建一个继承另一个类的类,但选择不继承特定方法吗?

一个简单的例子,我有一个抽象的Bird类,有一个方法fly()。我想为不同种类的鸟创建类,但企鹅不能飞。如何确保企鹅对象不能调用fly()方法?


在企鹅类中重写fly()方法,并使其抛出"I'm a Brick"异常。 - Marc B
我认为你需要有另一个子类别的类(另一级分类),你的设计需要改变。无论你在问什么,都不能立即完成。 - kosa
http://lostechies.com/derickbailey/files/2011/03/LiskovSubtitutionPrinciple_52BB5162.jpg - David
9个回答

12

不,你不能这样做。

最接近的方法是重写该方法并抛出异常。

@Override
public void fly() {
    throw new UnsuportedOperationException();
}
Java API有时会这样做,但我个人认为这是糟糕的设计。
你可以创建一个鸟类的层次结构,包含两个子类FlyableBird和NonFlyableBird,然后让企鹅成为NonFlyableBird的子类。这样fly方法只需要在FlyableBird类中实现。Bird类仍然可以包含像makeNoise()这样的方法(毕竟所有鸟类都会发出声音),这些方法对FlyableBird和NonFlyableBird都是通用的。

谢谢您的回复。我曾考虑过进一步细分类,但如果有更简单的方法,这似乎很麻烦。看来是时候学习如何抛出异常了。 - MrDetail
@MrDetail UnsupportedOperationException是运行时异常。查阅一下已检查和未检查异常之间的区别,这可能会对您的代码产生相当大的影响。 - RNJ
@RNJ 为了避免 UnsuportedOperationException,我们需要在 NonFlyableBirds 上重写 fly() 方法。根据 @MrDetail 的问题,他想确保企鹅对象不能调用 fly() 方法。但是建议的设计会调用 fly() 并抛出 UnsuportedOperationException。我认为需要为 NonFlyableBirds 调用 fly(),然后编写一些逻辑来避免飞行行为。 - Prasad S Deshpande
@PrasadSDeshpande 为什么在NonFlyableBirds中有fly()方法?如果没有它,你就不需要任何逻辑来避免飞行行为。 - RNJ

3
不可以这样做,因为这会从根本上破坏多态性。你需要实现该函数并执行类似于抛出异常或不执行任何操作的操作。

3

您需要有非常好的设计来实现您提到的场景。您需要像以下一样进行设计。

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();
}
}

2
你做不到。但是,你可以在企鹅的fly()方法中抛出一个UnsupportedOperationException

3
你应该使用UnsupportedOperationException。 - Matt Whipple

1
如果您需要做您正在尝试的事情,那么您的类/概念层次结构是错误的。重新设计您的类。

0

我认为,您可以创建一个名为Bird的主抽象类,并在其中定义像fly、walk等抽象方法。 然后,您可以创建两个Bird类的子类:FlyingBirds和NonFlyingBirds。在非飞行鸟的具体类中,您可以将fly方法设置为final。这样,该方法就不会被继承到子类中。


0

重写fly方法,将其指向另一个操作或在不执行该操作的情况下返回。


0

你可以将方法Fly声明为抽象方法,但如果你不提供实现,你将被迫将Penguin类也声明为抽象类,我认为这不是你想要的,因为企鹅不应该是抽象的,这没有任何意义。


0
你可以创建一个名为Fly的接口。然后,每个扩展了能够飞行的Bird类的具体类都应该实现这个接口。企鹅不会实现它,所以你的企鹅对象引用永远不会飞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接