首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >抽象类和抽象方法

抽象类和抽象方法
EN

Stack Overflow用户
提问于 2017-03-11 07:24:39
回答 4查看 251关注 0票数 0

我正在编写一个程序,其中我创建了一个抽象类Bird。在这个类中有一个名为chirp()的方法,它输出"chirp“。我做了另外两个类,名为Goose和Mallard,它们从Bird扩展而来,具有重写的chirp方法,可以打印出不同的声音:"Honk“和"Quack”。如果我要添加另一个名为Crow的类,这个类从Bird扩展而来,我该如何编写一个不重写的方法chirp呢?

我的方法是让一个方法具有不同的方法签名。我想我这样做了,但它没有像我想要的那样编译。

此外,如果我要在Bird中抽象该方法,我需要对crow类进行哪些更改……

以下是我到目前为止拥有的代码:

代码语言:javascript
复制
import java.util.Scanner;

public abstract class Bird {

    public void chirp() {
        System.out.println("chirp");
    }

    //if chirp made abstract
    public abstract void chirp();

}

public class Goose extends Bird {

    public void chirp() {
        System.out.println("Honk");
    }

}

public class Mallard extends Bird {

    public void chirp() {
        System.out.println("Quack");
    }

}

public class Crow extends Bird {

String sound;

public void chirp(String x) {
    sound = x;
} 

}

public class Problem10 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //Demonstration of polymorphism
        Bird goose = new Goose();
        Bird mallard = new Mallard();
        goose.chirp();
        mallard.chirp();


        //Reference Variable
        Bird bird = null;

        //Prompt the user to enter a number that is either 1 or 2
        Scanner scanner = new Scanner(System.in);
        System.out.println("Input number either 1 or 2: ");
        int inputInt = scanner.nextInt();
        if (inputInt == 1) {
            bird = new Goose();
        }
        else if (inputInt == 2) {
            bird = new Mallard();
        }
        else if (inputInt == 3) {
            bird = new Crow();
            bird.chirp("Crow");
        }
        bird.chirp();
    }

}
EN

回答 4

Stack Overflow用户

发布于 2017-03-11 07:37:51

对于抽象性,您有三种选择:

  • Bird是抽象的,但chirp不是:这意味着没有具体的“鸟”这样的东西。“鸟”是一个概括性的概念,像是把事物组合在一起。鸟是具体的这一事实意味着,如果不决定覆盖it.
  • Bird,所有的“鸟”都将默认说“chirp”是抽象的,chirp也是如此:与上面相同,除了现在没有默认的"chirp";任何“鸟”必须想出自己的chirping.
  • Bird方式不是抽象的,chirp也不是:在这种情况下,现在确实存在真正的具体的“鸟”,它们与“乌鸦”和“鸭子”等更多派生的东西不同。所有真正的“鸟”都说"chirp“,而更多派生类型的”鸟“将默认说"chirp”,除非他们决定改写它。

在所有这三种情况下,您可以将更多派生的“鸟”类型视为鸟,即使没有真正的混凝土鸟。

覆盖时,您也有多种选择:

  • 不覆盖:你得到的默认行为如上所述。如果方法是abstract.
  • Shadow:,这不是一个选项,这意味着派生类型越多,它就有一个与基类型同名的方法,但它实际上不会“覆盖”它。在这种情况下,如果你把一只鹅当成一只鹅,它会叫“鸣”,但如果你把一只鹅当成一只鸟,它会叫“嗡嗡”。换句话说,被调用的方法取决于您用来调用它的引用。(我不能100%肯定你能用Java语言做到这一点,而且我也找不到一个例子,所以far.)
  • Override:这意味着你确实覆盖了这个方法。即使你把一只鹅当成一只鸟,它仍然会叫“鸣”。这就是所谓的多态性,因为现在你可以有一个“鸟”的列表,即使你把它们当作鸟,它们也会以它们自己独特的被覆盖的方式来执行它们的任务。
票数 1
EN

Stack Overflow用户

发布于 2017-03-11 07:49:36

我认为你从你写的代码中得到了大约99%的结果。原因如下:

重载方法-具有相同名称但不同参数列表的方法-将不会相互冲突。

例如,如果您将抽象类保留为已定义的、具体的chirp方法,或者如果您仅定义了抽象方法,则只需将此代码添加到Crow类中,即可将其正确地转换为chirp

代码语言:javascript
复制
public class Crow extends Bird {

    String sound;

    // Use this to actually refer to Crow's chirp sound defined prior
    public void chirp() {
        System.out.println(sound);
    }

    public void chirp(String x) {
        sound = x;
    }

}

您可以很好地创建一个重载方法,但是如果您是从一个抽象类扩展而来的,那么您仍然需要根据您想要完成的任务来处理调用层次结构。如果Crow定义了自己的方法来根据其中的字段获取声音,那么您需要负责在该Crow实例上填充该字段。

票数 1
EN

Stack Overflow用户

发布于 2017-03-11 09:00:38

如果要调用由Bird变量引用Crow实例中的方法,

代码语言:javascript
复制
Bird crow = new Crow();

您需要在Bird中定义该方法,并在Crow中覆盖该方法。变量类型(Bird)在编译时确定变量可以达到的方法。对象类型(Crow)在运行时确定将实际运行哪个可能的重写。因此,如果希望Bird crow调用chirp(String),则Bird中必须存在这样的方法。

您可以通过构造函数、设置器或辅助方法在Crow中设置声音,从而解决此问题。

代码语言:javascript
复制
Bird bird = new Crow("croak");
bird.chirp();

代码语言:javascript
复制
Crow crow = new Crow();
crow.setSound("croak");
Bird bird = crow;
bird.chirp();

代码语言:javascript
复制
public class Crow {
  public void chirp() {
    play(getSound());
  }

  private Sound getSound() {
    Sound sound = // Figure out what sound
    return sound;
  }
}

选择取决于声音的确定需要有多动态。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42729379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档