Java:从抽象类和接口创建引用类型

时间:2014-12-04 12:44:53

标签: java oop interface abstract-class

我是Java新手,我读过线程(here),无法实例化抽象类。所以,我测试了它。

我做的第一个测试如下所示。似乎我实际上可以实例化一个抽象类,实际上,我实际上有一个新的类型,它引用了抽象类,并且实际上所有子类都共享了类型。这也意味着多态性适用。

import java.util.*;

abstract class AbstractClass{
    public abstract void printname();
}


class Test1 extends AbstractClass{

    private String name;

    public Test1(String name){
        this.name = name;
    }

    public void printname(){
        System.out.println("My name is " + name);
    }
}

class Test2 extends AbstractClass{
        private String saysomething;

    public Test2(String saysomething){
        this.saysomething = saysomething;
    }

    public void printname(){
        System.out.println(saysomething);
    }
}

class TestingApp{
    public static void main(String[] args){
        AbstractClass[] abstractclass_list = {new Test1("JEFFFFFF") , new Test2("Hey , say something")};
        for(AbstractClass item : abstractclass_list){
            item.printname();
        }
    }
}

然后我做了另一个测试,但这一次,我决定创建一个引用Interface的类型,而不是在抽象类上工作。看起来我也可以实例化一个接口。我实际上可以创建一个引用接口的类型。实现此接口的所有类共享此类型。并且多态性再次适用。

import java.util.*;

interface  AbstractInterface{
    public void printname();
}


class Test4 implements AbstractInterface{

    private String name;

    public Test4(String name){
        this.name = name;
    }

    public void printname(){
        System.out.println("My name is " + name);
    }
}

class Test3 implements AbstractInterface{
    private String saysomething;

    public Test3(String saysomething){
        this.saysomething = saysomething;
    }

    public void printname(){
        System.out.println(saysomething);
    }
}

class TestingAbstractInterfaceApp{
    public static void main(String[] args){
        AbstractInterface[] abstract_list = {new Test4("Helen") , new Test3("Hey , say my name")};
        for(AbstractInterface item : abstract_list){
            item.printname();
        }
    }
}

问题:

我感觉我在代码中所做的事情有问题。但是我无法解释为什么代码在理论上仍然有效,不可能实例化一个抽象类和接口。我实际上是在上面显示的示例中实例化一个抽象类和一个接口吗?因为这看起来就像我所做的那样,因为我有一个抽象类和接口的新类型。如果我的逻辑错误或我使用了错误的词语,请纠正我。

更新 所以我想我的误解是关于类型。我一直认为type只能引用普通的Java类,而不能引用抽象的类和接口。怎么"键入"实际上工作?它是否正在创建参考?

5 个答案:

答案 0 :(得分:3)

为什么您认为实际上是在实例化AbstractClassAbstractInterface

new Test1("JEFFFFFF") , new Test2("Hey , say something"), new Test4("Helen") , new Test3("Hey , say my name")都是实例化的具体类,而不是抽象类。

如果您将AbstractClass[] abstractclass_list =称为实例化抽象类的证据,那就错了。在这里,您声明一个数组类型为AbstractClassTest1Test2的数组(因为它们extend AbstractClass)。

<强>更新

你可以拥有类似AbstractClass abs = new Test1("hey");之类的东西,它的作用是创建一个新的类Test1实例,并从变量abs引用该实例。 abs的具体类型为Test1,但只有AbstractClass中声明的方法才可见。如果您想调用Test1的方法,则必须先将其强制转换。

AbstractClass abs = new Test1("hey");
abs.printname(); // this is ok, and it calls `printname() implemented in Test1
abs.someTest1Method(); // this is NOT ok, someTest1Method() is not visible to abs
((Test1)abs).someTest1Method(); // this is ok, abs is cast to Test1, but would fail if abs was instantiated as 'abs = new Test2("t2")' (would throw ClassCastException)

答案 1 :(得分:1)

您没有实例化您的抽象类或您的界面。您正在实例化扩展抽象类(Test1Test2)的具体类,或实现您的接口(Test3Test4)。

允许将具体类的实例分配给类型为接口或抽象类的变量。事实上,它甚至受到了鼓励。

答案 2 :(得分:1)

您既不是实例化抽象类,也不是实例。您只是使用从子类到超类的固有向上转换功能。

忽略数组,只使用第一个对象,这相当于隐式的upcast:

AbstractClass myObject = new Test1("JEFFFFFF");

AbstractInterface myObject = new Test1("JEFFFFFF");

所以,在代码中:

  AbstractClass[] abstractclass_list = {
     new Test1("JEFFFFFF") , 
     new Test2("Hey , say something")};

您正在实例化具体类Test1Test2的对象 - Array包含对底层(和公共)抽象基类的引用。

同样,在第二个示例中,您将获得一个接口引用数组。

答案 3 :(得分:1)

总之我想说的是,
Parent(here, Abstract/Iterface)可以引用,child(here, concrete class)

所以在这里,引用变量可以引用它的子类的实例。

在你的大脑中注意这个概念,它将解决你所有的问题,动态调度程序,继承相关...... !!!

答案 4 :(得分:0)

您不是instantiating abstract班级和interface

instantiatingimplementationsabstractinterface AbstractClass

如果声明AbstractInterface或{{1}}的列表,则可以只调用在超类或接口上声明的方法,但不能调用在特定实现(Test1,Test2,Test3和Test4)上声明的方法。< / p>