为什么我们需要抽象类中的构造函数和私有成员?这不像我们要创建该类的实例。
答案 0 :(得分:14)
你将创建实例,只是派生类的实例。那些派生类仍然需要调用构造函数,并且仍然可以调用抽象类的成员 - 这可能反过来使用私有成员。
这是一个例子(不是非常有用的,只是为了展示基本想法......)
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 + ")";
}
}
我不能说我经常编写 抽象类,通常更喜欢使用组合继承,但是当我做创建它们时,我当然会使用构造函数和私有成员。 / p>
答案 1 :(得分:3)
抽象类提供了某些接口的部分实现。考虑到您可能希望提供部分实现并禁止客户端代码(具体子类)访问特定内容(即封装原则的扩展),这是完全合理的。
将某些成员标记为私有强制继承类以调用受保护的方法来访问该部分实现;提供构造函数允许子类在自己构造期间初始化父级的封装状态。
答案 2 :(得分:1)
与接口不同,定义数据字段的抽象类实际上是在分配这些数据字段的意义上实例化的。只是它们永远不会自己实例化,它们被实例化为更大的东西 - 子类。因此,当构建子类时,也会构建超类型,这就是为什么需要构造函数。
根据您的层次结构,您的抽象类可能具有含义和状态。例如,如果您的申请是学校,您可能拥有一个人的概念(具有姓名和SSN),但您可以为学生和教师提供不同的子类型。因为两种类型的人共享某些状态结构(名称和SSN),所以两个类都会扩展Person类。但是你永远不会直接实例化一个人。
答案 3 :(得分:0)
除了Jon的回答之外,我还想提一下,如果你让子类树保持浅薄,抽象类仍然可以很好地用于组合。即它非常适合为一些密切相关的对象提供公共基类,但不能创建一个巨大的子类树。
答案 4 :(得分:0)
为什么需要私人课程?我认为你将抽象类与接口混淆。与接口不同,抽象类可以保存功能。例如:
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,但通过声明成员和构造函数,您可以自定义类的功能(这称为模板方法)。
答案 5 :(得分:0)
假设您正在进行临时代码或原型设计,您可以不时地实例化抽象类(甚至可能是接口)。他们被称为匿名内部类(one,two),看起来像这样:
// 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。