是否可以调用子类? 超类对象上的方法?

发布于 2024-07-21 05:28:38 字数 481 浏览 6 评论 0原文

Animal 是 Dog 的超类 Dog 有一个名为 bark 的方法

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

考虑以下内容:

Animal a = new Dog();
if (a instanceof Dog){
    a.bark();
}

会发生什么?

  1. 不允许赋值
  2. 允许调用 bark,并在运行时打印“woof”
  3. 允许调用 bark,但不打印任何内容
  4. 对 bark 的调用导致编译时错误
  5. 对 bark 的调用导致运行时错误

我说 2 是因为我们正在检查该物体是否是一只狗; 因为狗是其中包含 bark 方法的类,如果是,那么我们调用它,它将打印出 :s

我的理解正确吗?

Animal is a superclass of Dog
and Dog has a method called bark

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

Consider the following:

Animal a = new Dog();
if (a instanceof Dog){
    a.bark();
}

What will happen?

  1. the assignment isn't allowed
  2. the call to bark is allowed and "woof" is printed at run time
  3. the call to bark is allowed but nothing is printed
  4. the call to bark causes a compile time error
  5. the call to bark results in a run time error

I said 2 as we are checking if the object is a dog; as dog is the class with the bark method in it, if it is then we call it which will print out :s

Is my understanding correct here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

二智少女 2024-07-28 05:28:38

这不会编译,因为 Animal 没有名为 bark 的方法。 可以这样想,所有的狗都是动物,但并非所有的动物都是狗。 所有的狗都会吠叫,但并非所有的动物都会吠叫。

This won't compile since Animal does not have a method called bark. Think of it this way, all dogs are animals, but not all animals are dogs. All dogs bark, but not all animals bark.

无边思念无边月 2024-07-28 05:28:38

不——答案是;

4) 对 bark 的调用导致编译时错误

bark 方法未定义为指定类型 Animal 上的方法,因此将导致编译时问题; 这可以通过铸造来解决;

((Dog)a).bark();

no - the answer is;

4) the call to bark causes a compile time error

the bark method isnt defined as a method on the assigned type Animal, which will therefore result in compile time issue; this could be solved by casting;

((Dog)a).bark();
寄意 2024-07-28 05:28:38

关键在于以下行:

Animal a = new Dog();

虽然创建了 Dog 的新实例,但它的引用是由 a 声明的,该实例被声明为 Animal 类型代码>. 因此,任何对 a 的引用都会使 new Dog 被作为 Animal 处理。

因此,除非 Animalbark 方法,否则以下行将导致编译器错误:

a.bark();

即使 a 已被测试以查看它是否是一个Dog 的实例,并且 a instanceof Dog 实际上会返回 true,变量 a 仍然是 is 类型Animal,因此 if 语句内的块仍将 a 作为 Animal 处理。

这是静态类型语言的一项功能,其中变量提前分配类型,并在编译时检查类型是否匹配。 如果此代码在动态类型语言上执行,其中类型在运行时检查,可以允许类似以下内容:

var a = new Dog();
if (a instanceof Dog)
    a.bark();

a.bark() 保证仅在实例是 Dog 时执行,因此对 bark 的调用代码> 永远有效。 但是,Java 是静态类型语言,因此不允许这种类型的代码。

The key is in the following line:

Animal a = new Dog();

Although a new instance of Dog was created, its reference is by a which is declared to be of the type Animal. Therefore, any references to a makes the new Dog be handled as an Animal.

Therefore, unless Animal has a bark method, the following line will cause a compiler error:

a.bark();

Even though a is tested to see if it is an instance of Dog, and a instanceof Dog will actually return true, the variable a is still of is of type Animal, so the block inside the if statement still handles a as an Animal.

This is a feature of statically-typed languages where variables are assigned a type ahead of time, and checked at compile-time to see that the types match. If this code were performed on a dynamically-typed language, where the types are checked at runtime, something like the following could be allowed:

var a = new Dog();
if (a instanceof Dog)
    a.bark();

a.bark() is guaranteed only to execute when the instance is a Dog, so the call to bark will always work. However, Java is a statically-typed language, so this type of code is not allowed.

伤痕我心 2024-07-28 05:28:38

Head First Java 中,他们使用了电视遥控器的很好的比喻作为参考 /em> 和您的电视作为引用指向的对象。 如果您的遥控器只有开、关、频道加减、音量加减的按钮(方法),那么您的电视有什么炫酷的功能并不重要。 您仍然只能通过遥控器执行一些基本操作。 例如,如果您的遥控器没有静音按钮,则您无法将电视静音。

Animal 参考仅了解 Animal 方法。 无论底层对象有什么其他方法,您都无法从 Animal 引用访问它们。

In Head First Java they use the very good analogy of a TV remote control for a reference and your TV as the object that the reference points to. If your remote only has buttons (methods) for on, off, channel up and down, and volume up and down, it doesn't matter what cool features your TV has. You can still only do those few basic things from your remote. You can't mute your TV, for example, if your remote has no mute button.

The Animal reference only knows about Animal methods. It doesn't matter what other methods the underlying object has, you can't access them from an Animal reference.

微暖i 2024-07-28 05:28:38

是 4。你不能要求一个普通的动物(你的代码中的 a 是这样的)吠叫。 因为你可以很容易地说出来

Animal a = new Cat();

,但吠叫线无法知道你没有说过。

It's 4. You can't ask a generic Animal - which is what your code says a is - to bark. Because you could just as easily have said

Animal a = new Cat();

and the bark line doesn't have a way to know that you didn't.

有木有妳兜一样 2024-07-28 05:28:38

如果想法是从超类对象打印子类方法,那么这将起作用:

而不是 Animal a = new Dog(); if (Dog 的一个实例){ a.bark(); }
更改为

Animal a = new Dog();

if (a instanceof Dog){ 
    Dog d = (Dog) a; 
    d.bark();
}  

这将超类转换回子类并打印它。
尽管它的设计很糟糕,但它是动态了解其指向哪个子类对象的一种方法。

If the idea is to print the subclass method from superclass object, this will work:

Instead of Animal a = new Dog(); if (a instanceof Dog){ a.bark(); }
change to

Animal a = new Dog();

if (a instanceof Dog){ 
    Dog d = (Dog) a; 
    d.bark();
}  

This casts the superclass back to subclass and prints it.
although its bad design, its one way to know which child class object its pointing to dynamically.

命硬 2024-07-28 05:28:38

在java(我知道的唯一语言)中,您可以创建一个空方法并在超类中调用它。 然后你可以在子类中重写它来做你想做的事情。 这样超类调用其子类的方法。

public class Test {
    public static void main(String[] args){
        Snake S = new Snake();
        Dog d = new Dog();
    }
}


class Animal{ //Super Class
    public Animal(){
        bark(); //calls bark when a new animal is created
    }
    public void bark(){
        System.out.println("this animal can't bark");
    }
}



class Dog extends Animal{ //Subclass 1
    @Override
    public void bark(){
        System.out.println("Woof");
    }
}



class Snake extends Animal{//Subclass 2
    public void tss(){
    }
}

此代码调用 Snake 的对象,然后调用 Dog 的对象。 它将以下内容写入控制台:

this animal can't bark
Woof

Snake 没有任何 bark 方法,因此调用超类的方法。 它将第一行写入控制台。
Dog 有一个 bark 方法,因此超类调用它。 它将第二行写入控制台。

In java(only language i know) you can create an empty method and call it in super class. Then you can override it in subclass to do whatever you want. This way the super class calls its subclass' method.

public class Test {
    public static void main(String[] args){
        Snake S = new Snake();
        Dog d = new Dog();
    }
}


class Animal{ //Super Class
    public Animal(){
        bark(); //calls bark when a new animal is created
    }
    public void bark(){
        System.out.println("this animal can't bark");
    }
}



class Dog extends Animal{ //Subclass 1
    @Override
    public void bark(){
        System.out.println("Woof");
    }
}



class Snake extends Animal{//Subclass 2
    public void tss(){
    }
}

This code calls an object of Snake then calls an object of Dog. It writes this to console:

this animal can't bark
Woof

Snake doesn't have any bark method so super class' method is called. It writes the first line to the console.
Dog has a bark method so super class calls it instead. It writes the second line to the console.

梦中的蝴蝶 2024-07-28 05:28:38

仅供参考,这不是一个好的设计。

几乎任何时候您拥有这种形式的代码:

if (x instanceof SomeClass)
{
   x.SomeMethod();
}

您都在滥用类型系统。 这不是使用类的方法,也不是编写可维护的面向对象代码的方法。 它很脆。 很复杂。 这不好。

您可以在基类中创建模板方法,但它们必须调用基类中存在并在子类中重写的方法。

FYI, this is not a good design.

Just about any time you have code of this form:

if (x instanceof SomeClass)
{
   x.SomeMethod();
}

you are abusing the type system. This is not the way to use classes, it's not the way to write maintainable object oriented code. It's brittle. It's convoluted. It's bad.

You can create template methods in a base class, but they have to call methods that exist in the base class and are overridden in sub-classes.

盗心人 2024-07-28 05:28:38

“我说 2 是因为我们正在检查该对象是否是狗;因为狗是其中包含 bark 方法的类,如果是,那么我们调用它,它将打印出:s”

“我说 2 是因为我们正在检查该对象是否是狗;因为狗是其中包含 bark 方法的类,如果是, 是正确的,但这不是它的工作方式。

Java 是一种静态类型语言,这意味着对象可能响应的方法的有效性在编译时进行验证。

您可能认为支票:

if( a instanceof Dog ) 

可以,但实际上不行。 编译器所做的是检查声明类型的“接口”(在本例中为 Animal )。 “接口”由 Animal 类上声明的方法组成。

如果超类 Animal 中没有定义 bark() 方法,编译器会说:“嘿,那不起作用”。

这很有用,因为“有时”我们在编码时会犯错(例如输入 barck() )。

如果编译器没有警告我们这一点,您将必须在“运行时”找到它,并且并不总是有一个明确的提示。消息(例如 IE 中的 javascript 表示类似“意外对象”之类的内容)

不过,像 java 这样的静态类型语言允许我们强制调用。 在本例中,它使用“强制转换”运算符 ()

像这样

1. Animal a = new Dog();
2.  if (a instanceof Dog){
3.     Dog imADog = ( Dog ) a;
4.     imADog.bark();
5. }

在第 3 行中,您正在“强制转换”为 Dog 类型,以便编译器可以检查 bark 是否是有效消息。

这是向编译器发出的指令,“嘿,我是这里的程序员,我知道我在做什么”。 编译器检查,Ok,dog,可以接收消息 bark(),继续。 然而,如果在运行时动物不是狗,则会引发运行时异常。

演员阵容也可以缩写为:

if( a instanceof Dog ) {
   ((Dog)a).bark();  
}

That will run。

所以,正确的答案是4:对 bark 的调用导致编译时错误

我希望这会有所帮助。

"I said 2 as we are checking if the object is a dog; as dog is the class with the bark method in it, if it is then we call it which will print out :s"

Your rationale is correct, but that's not the way it works.

Java is an static typed language that means, the validity of the methods an object may respond to is verified at compile time.

You may think the check:

if( a instanceof Dog ) 

Would do, but actually it doesn't. What the compiler do is check against the "interface" of the declared type ( Animal in this case ). The "interface" is composed of the methods declared on the Animal class.

If the bark() method is not defined in the super class Animal the compiler says: "Hey, that won't work".

This is helpful, because "sometimes" we make typos while coding ( typing barck() instead for instance )

If the compiler doesn't not warn us about this, you would have to find it at "runtime" and not always with a clear message ( for instance javascript in IE says something like "unexpected object" )

Still, static typed language like java allow us to force the call. In this case it is using the "cast" operator ()

Like this

1. Animal a = new Dog();
2.  if (a instanceof Dog){
3.     Dog imADog = ( Dog ) a;
4.     imADog.bark();
5. }

In line 3 your are "casting" to a Dog type so the compiler may check if bark is a valid message.

This is an instruction to to compiler saying "Hey I'm the programmer here, I know what I'm doing". And the compiler, checks, Ok, dog, can receive the message bark(), proceed. Yet, if in runtime the animal is not a dog, a runtime exception will raise.

The cast could also be abbreviated like:

if( a instanceof Dog ) {
   ((Dog)a).bark();  
}

That will run.

So, the correct answer is 4: "the call to bark causes a compile time error"

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文