繁体   English   中英

为什么我们需要抽象类中的构造函数和私有成员?

[英]Why do we need constructors and private members in the abstract class?

为什么我们需要抽象类中的构造函数和私有成员? 这并不像我们要创建该类的实例。

创建实例,只是派生类的实例。 那些派生类仍然需要调用构造函数,并且仍然可以调用抽象类的成员 - 这可能反过来使用私有成员。

这是一个例子(不是一个非常有用的例子,但只是为了展示基本的想法......)

public abstract class NamedObject
{
    private final String name = name;

    protected NamedObject(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }
}

public class Computer extends NamedObject
{
    private final int processorSpeed;

    public Computer(String name, int processorSpeed)
    {
        super(name); // See, the constructor is useful
        this.processorSpeed = processorSpeed;
    }

    public String toString()
    {
        return getName() + " (" + processorSpeed + ")";
    }
}

我不能说我写的抽象类往往 ,一般倾向于组成继承,但是当我创建它们我当然使用构造函数和私有成员。

抽象类提供了某些接口的部分实现。 考虑到您可能希望提供部分实现并禁止客户端代码(具体子类)访问特定内容(即封装原则的扩展),这是完全合理的。

将某些成员标记为私有强制继承类以调用受保护的方法来访问该部分实现; 提供构造函数允许子类在自己构造期间初始化父级的封装状态。

与接口不同,定义数据字段的抽象类实际上是在分配这些数据字段的意义上实例化的。 只是它们永远不会自己实例化,它们被实例化为更大的东西 - 子类。 因此,在构建子类时,也会构建超类型,这就是为什么需要构造函数的原因。

根据您的层次结构,您的抽象类可能具有含义和状态。 例如,如果您的申请是学校,您可能拥有一个人的概念(具有姓名和SSN),但您可以为学生和教师提供不同的子类型。 因为两种类型的人共享某些状态结构(名称和SSN),所以两个类都会扩展Person类。 但是你永远不会直接实例化一个人。

除了Jon的回答之外,我还想提一下,如果你让子类树保持浅薄,那么抽象类仍然可以很好地用于组合。 也就是说,为一些密切相关的对象提供公共基类是很好的,但不是为了创建一个巨大的子类树。

你为什么需要私人课程? 我认为你将抽象类与接口混淆。 与接口不同,抽象类可以保存功能。 例如:

public class AbstractBase{
    private int num;

    public AbstractBase(int number){
       this->num = number;
    }

    public int method(){
       return ( this->num * this->templateMethod());
    }

    public abstract int templateMethod();
 }

公共类ConcreteDerived扩展AbstractBase {

public ConcreteDerived(){
  super(4);
}

public int templateMethod(){
   return number; //number is the result of some calculation
}

}

在此示例中,您永远不会显式实例化AbstractBase,但通过声明成员和构造函数,您可以自定义类的功能(这称为模板方法)。

假设您正在进行临时代码或原型设计,您会不时地实例化抽象类(甚至可能是接口)。 他们被称为匿名内部类( ),看起来像这样:

// you have this...
public abstract class SomeClass {
    public abstract String returnAString();
}

// ...and this...
public class OtherClass {
    public void operate(SomeClass c) {
        System.out.println(c.returnAString());
    }
}

// ...so you do this:    
OtherClass oc = new OtherClass();
// this is one of the reasons why you need to specify a constructor
oc.operate(new SomeClass() {
    @Override
    public String returnAString() {
        return "I'm an anonymous inner class!";
    }
});

这个例子当然是多余的,但应该揭示这一点。 一些现有的框架甚至依赖于这种行为的大量使用,至少是Apache Wicket

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM