java - 当对象是 Java 中的接口(interface)引用时的类型转换

标签 java inheritance interface casting

我熟悉继承模型中的类型转换

SuperClass和SubClass成为父类和子类;

父类(super class) superClass = new SubClass(); -- 这里实例化的对象是一个子类对象; 但是它的引用类型SuperClass;也就是说只有SuperClass的那些方法可以在子类对象上被调用; subclass 中任何inherited/overriddenmethods 都不能被调用(即 的任何独特methods >子类).

如果 SuperClass 是一个接口(interface) 并且 SubClass 实现它,我观察到与上面相同的行为。只有那些在 SuperClass interface 中声明的方法才可以在 SubClass 对象上调用。我的理解正确吗?但是通过一些转换,我可以调用不属于接口(interface)的方法,我在下面的示例代码中观察到了这一点;

我已经就我对它如何运作的理解发表了一些评论; 但我想知道这是否有意义,或者我的解释是否错误;

class Animals {

     public void bark(){
         System.out.println("animal is barking");
     }

}

 interface catIF {
     public void catting();

 }

interface dogIF {
    public void dogging();
 }

class Dog extends Animals implements dogIF {

    public void bark(){
        System.out.println("dog is barking");
    }


    public void dogging() {
        System.out.println("dogging");

    }

}

class Cat extends Animals implements catIF {

    public void bark(){
        System.out.println("cat is barking");
    }


    public void catting() {
        System.out.println("catting");

    }

}

public class Animal {

    public static void main(String[] args){
        dogIF dog = new Dog();
        //dog.bark(); this fails
        //This method actually actually exists;
        //but it is not available or hidden because dogIF reference
        //limits its availability; (this is similar to inheritance)

        Dog dog2 = new Dog();
        dog2.bark();
        ////prints dog is barking

        Animals an =(Animals) dog;
        an.bark();
        //prints dog is barking
        //by casting we mean, treat the dog as an animals reference
        //but the object itself is a dog.
        //call the bark() method of dog
        //but dog did not have this method in the beginning (see first line
        // in main - when instantiated with interface type)
        }
     }

最佳答案

接口(interface)的继承确实不“脆弱”或复杂。它们的行为与抽象类完全相同,除了您以不同方式引用它们(实现而不是扩展)以及您可以继承任意数量的接口(interface)但只能有一个父类(super class)(抽象或非抽象)。

与其他继承一样:如果您对一个对象的了解只是它实现了一个接口(interface),那么您只能通过该接口(interface)访问它。如果您知道它实现了另一个接口(interface),或特定的父类(super class),或者是特定类的实例,那么您可以将它转换为那些并通过这些的公开成员访问它。

所以,是的:如果您的程序只知道该对象是 Animals 的一个实例,那么您所能做的就是调用 Animals 上声明的内容。这意味着 bark() 加上它从 Object 继承的任何方法(因为即使没有明确说明,一切都是直接或间接的 Object ).

如果您的程序知道该对象是 dogIFcatIF 的实现——因为变量类型表明它是,或者因为您已经成功地将它类型转换为这些接口(interface)之一——您还可以调用这些接口(interface)声明的方法。顺便说一句,接口(interface)的通常约定是像类一样命名它们,使用 UppercasedFirstLetter... 因为在许多情况下,接口(interface)和类之间的区别对于使用它的人来说并不重要。

如果您的程序碰巧知道对象是 Dog,您可以调用它从 AnimalsdogIF 继承的任何对象,或者由 Dog 直接提供。当然它实际上可能是一只 Chihuahua(狗的子类),但没关系,子类将以“维护语义的正确方式”响应父类(super class)会响应的任何内容。 (也就是说,Chihuahua 可能会通过说“yip yip yip grr yip!”来响应 bark(),但这种方法真的不应该让它尝试咬人你的脚踝。)

希望对您有所帮助。它真的没有那么复杂。

关于java - 当对象是 Java 中的接口(interface)引用时的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21561214/

相关文章:

java - 在 Java 中为线程池提供单独的微服务有意义吗?

C++派生类

php - 一个子类没有额外属性时的 Doctrine 表类继承

go - 试图将文字转换为 Golang 中的指针

Javafx 在对象更改时更新 TableView

java - 如何将 map 的 map 列表合并为 map 的 map ?

ios - 从概念上讲,子类化 UIView 是否正确?

C#如何在运行时动态生成一个实现不同接口(interface)的对象?

java - 接口(interface)是否扩展了Object类?

java - 在下面代码的内循环中使用 break 不是更有意义吗?