Day06:爸爸这麽做都是为你好

当我们在定义类别时,有三种东西可以定义,属性(field)、建构子(constructor)、方法(method)。今天要来谈谈建构子,建构子有些需要刻意注意的潜规则。

  1. 预设建构子(Default Constructor)
    假设我们今天定义了一个Player的类别:
class Player{
    String name;
    int age;
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return this.age;
    }
}

看似我们只定义了属性跟方法,但实际上Java会存在一个预设的空建构子:

Player(){

}

有趣的是,若类别有父类别,则子类别的建构子会**隐藏的呼叫父类别的预设建构子;若父类别没有预设建构子时,子类别除了必须自行定义建构子外,还必须在建构子讲明要呼叫哪个父类别建构子。**那为什麽会没有预设建构子?因为只要我们建立了自行定义的建构子,Java就不会帮我们建立预设的空建构子了。

  1. 自行定义建构子
    若在Player类别中我们自己定义了一个可以传入name建立Player实例的建构子:
class Player{
    String name;
    int age;
    
    Player(String name){
        this.name = name;
    }
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return this.age;
    }
}

这样的话,在程序中要new出这个类别的实例时,都必须透过这个传入name引数的建构子了!无法new Player()这样不传入参数创建Player实例。而且当有类别继承Player时,该子类别的建构子就必须写出要如何呼叫出这个父类别的建构子(必须写在子类别建构子的第一行,ex: super(name);)。听起来颇麻烦的对不对?能不能有自行定义的建构子,同时也可以让子类别的建构子不特别指定父类别建构子,或者可以不自行定义建构子?

  1. 自行定义的空建构子(Nullary Constructor)
    答案其实很简单暴力,那就是自己定义一个空的建构子~
class Player{
    String name;
    int age;
    
    Player(){
    }
        
    Player(String name){
        this.name = name;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public int getAge(){
        return this.age;
    }
}

这样一来,继承Player的子类别就可以达到不需撰写任何建构子的目的了。

小结:

  1. 若类别没有定义任何建构子,Java会隐含一个预设建构子(Default Constructor)
  2. 当我们自行撰写了任何形式的建构子後,预设建构子就不存在了,且子类别也必须定义出建构子,并在子类别建构子的第一行定义要呼叫哪个父类别建构子
  3. 若我们希望子类别可以不用撰写任何建构子,或者子类别的建构子不用特别定义如何呼叫父类别建构子,那只要在父类别中自行定义出空建构子(Nullary Constructor),Java就会自动在子类别建构子中隐含呼叫这个空建构子
  4. 本质上,预设建构子和空建构子是一样的东西,就是没有定义任何参数以及实作内容的建构子

<<:  Day 19 - 安装 AlexeyAB/darknet ON Amazon Linux 2

>>:  ESP32_DAY4 用VS Code开范例程序

Day.23 Binary Search Tree

终於讲到树,快接近尾声了(烟 二元搜寻图(Binary Search Tree)是一种很高效的资料结...

ShadowsocksR/SSR客户端

ShadowsocksR常被称为SSR、酸酸乳、小飞机(粉色)、纸飞机(粉色),是由“破娃酱”发起的...

型一错误与型二错误(Type I error & Type II error)

接受和拒绝以及匹配和不匹配对於生物识别背景下的交流非常有效。我们是否需要将它们与二元分类中使用的 N...

【day2】突然想吃樱桃鸭握寿司之典华烤鸭

前阵子突然很想念樱桃鸭握寿司 因为疫情关系又不方便呼朋引伴到礁溪吃一顿 意外的在天母地区发现典华系列...

Day 17:Layout Using Grid

介绍了 juce::Rectangle 以及 juce::FlexBox 这两个拉版工具後,这篇介绍...