《JAVA编程思想》学习备忘(第237页:Reusing Classes)-2

本文深入探讨了Java中构造函数的调用顺序及如何正确初始化基类对象,通过具体示例展示了带参数构造函数的使用,并介绍了委托模式作为继承与组合之间的中间方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

续《JAVA编程思想》学习备忘(第237页:Reusing Classes)-1  
Initializing the base class
...it's essential that the base-class subobject be initialized correctly,and there's only one way to guarantee this:Perform the initialization in the constructor by calling the base-class constructor,which has all the appropritate knowledge and privileges to perform the base-class initialization.
示例:
//:reusing/Cartoon.java
//Constructor calls during inheritance.
import static net.mindview.util.Print.*;
class Art{
    Art(){print("Art constructor");}
}
class Drawing extends Art{
    Drawing(){print("Drawing constructor");}
}
public class Cartoon extends Drawing{
    public Cartoon(){print("Cartoon constructor");}
    public static void main(String[] args){
        Cartoon x = new Cartoon();
    }
}
输出结果:
Art constructor
Drawing constructor
Cartoon constructor
You can see that the construction happens from the base"outward,"so the base class is initialized before the derived-class constructors can access it.Even if you don't create a constructor for Cartoon(),the compiler will synthesize a default constructor for you that calls the base-class constructor.
补充示例:(将最后一个类的构造方法注释掉看看效果)
public class Cartoon extends Drawing{
    //public Cartoon(){print("Cartoon constructor");}
    public static void main(String[] args){
        Cartoon x = new Cartoon();
    }
}
输出结果:
Art constructor
Drawing constructor
 
Constructors with arguments
The preceding example has default constructors:that is, they don't have any arguments.It's easy for the compiler to call these because there's no question about what arguments to pass.If there is no default base-class constructor,or if you want to call a base-class constructor that has arguments,you must explicitly write a call to the base-class constructor using the super keyword and the appropriate argument list:
//:reusing/Chess.java
//Inheritance,constructors and arguments.
import static net.mindview.util.Print.*;
class Game{
    Game(int i){
        print("Game constructor");
    }
class BoardGame extends Game{
    BoardGame(int i){
        super(i);
        print("BoardGame constructor");
    }
}
public class Chess extends BoardGame{
    Chess(){
        super(11);
        print("Chess constructor");
    }
    public static void main(String[] args){
        Chess x = new Chess();
    }
}
输出结果:
Game constructor
BoardGame constructor
Chess constructor
 
If you don't call the base-class constructor in BoardGame(),the compiler will complain that it can't find a constructor of the form Game().In addition,the call to the base-class constructor must be the first thing you do in the derived-class constructor.(The compiler will remind you if you get it wrong.)
 
Delegation
A third relationship,which is not directly supported by Java,is called delegation.This is midway between inheritance and composition,because you place a member object in the class you're building(like composition),but at the same time you expose all the methods from the member object in your new class(like inheritance).For example,a spaceship needs a control module:
//:reusing/SpaceShipControls.java
public class SpaceShipControls{
    void up(int velocity){}
    void down(int velocity){}
    void left(int velocity){}
    void right(int velocity){}
    void forward(int velocity){}
    void back(int velocity){}
    void turboBoost(){}
}
One way to build a spaceship is to use inheritance:
//:reusing/SpaceShip.java
public class SpaceShip extends SpaceShipControls{
    private String name;
    public SpaceShip(String name){this.name = name;}
    public String toString(){return name;}
    public static void main(String[] args){
        SpaceShip protector = new SpaceShip("NSEA Protector");
        protector.forward(100);
    }
}
However,a SpaceShip isn't really"a type of"SpaceShipControls,even if,for example,you"tell"a SpaceShip to go forward().It's more accurate to say that a SpaceShip contains SpaceShipControls,and at the same time all the methods in SpaceShipControls are exposed in a SpaceShip.Delegation solves the dilemma:
关于“Delegation”的示例:
//:reusing/SpaceShipDelegation.java
public class SpaceShipDelegation{
    private String name;
    private SpaceShipControls controls = new SpaceShipControls();
    public SpaceShipDelegation(String name){
        this.name = name;
    }
    //Delegated methods:
    public void back(int velocity){
        controls.back(velocity);
    }
    public void down(int velocity){
        controls.down(velocity);
    }
    public void forward(int velocity){
        controls.forward(velocity);
    }
    public void left(int velocity){
        controls.left(velocity);
    }
    public void right(int velocity){
        controls.right(velocity);
    }
    public void turboBoost(){
        controls.turboBoost();
    }
    public void up(int velocity){
        controls.up(velocity);
    }
    public static void main(String[] args){
        SpaceShipDelegation protector =
           new SpaceShipDelegation("NSEA Protector");
        protector.forward(100);
    }
}
You can see how the methods are forwarded to the underlying controls object,and the interface is thus the same as it is with inheritance.
(待续)
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值