当对象是 Java 中的接口引用时的类型转换

bra*_*orm 1 java inheritance casting interface

我熟悉type castingin inheritance model.

SuperClass and SubClass是父子类;

SuperClass superClass = new SubClass(); -- 这里object实例化的是一个subclass object; 但它reference typeSuperClass;这仅仅是对那些methodsSuperClass可以在被调用subclass object; 任何methods不在inherited/overridden中的subclass都不能被调用(这是 的任何唯一methodssubclass)。

我观察到与上面相同的行为 ifSuperClass is an interfaceSubClass implements it。也就是说,只有在SuperClass interface中声明的方法才能在SubClass对象上调用。我的理解正确吗?但是对于一些casting,我可以调用methods它不是接口的一部分,我在下面的示例代码中观察到了这一点;

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

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)
        }
     }
Run Code Online (Sandbox Code Playgroud)

kes*_*lam 5

接口的继承实际上并不“脆弱”或复杂。它们的行为与抽象类完全一样,除了您以不同方式引用它们(实现而不是扩展),并且您可以继承任意数量的接口,但只能有一个超类(抽象与否)。

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

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

如果您的程序知道该对象是dogIFor的实现catIF——因为变量类型表明它是,或者因为您已成功将其类型转换为这些接口之一——您还可以调用这些接口声明的方法. 顺便说一下,接口的通常约定是将它们命名为类,用大写首字母...因为在许多情况下,接口和类之间的区别对于使用它的人来说实际上并不重要。

如果您的程序碰巧知道该对象是Dog,您可以调用它从Animals或继承的任何东西dogIF,或者直接由Dog. 当然,它实际上可能是一个Chihuahua(狗的子类),但是没关系,子类将以“保持语义的正确方式”响应超类会响应的任何内容。(也就是说,aChihuahua可能会bark()说“yip yip yip grr yip!”,但这种方法真的不应该让它试图咬你的脚踝。)

希望有帮助。真的没有那么复杂。