[Day22] CH11:刘姥姥逛物件导向的世界——封装性、继承性

今天要来介绍物件导向的三大特性:封装性、继承性、多型性。

封装性(Encapsulation)

可以将物件区分为可被外界使用的特性或受保护的内部特性,也就是说外部程序无法改变物件内的资料,这样一来就可以达到封装保护资料的特性。

举个例来说,今天你要开车,你只需要知道如何转动方向盘、打档,不需要知道引擎如何运作。

先前已经介绍过 public(公开)和 private(私人),其实还有第三种 protected(保护)

  • public(公开):允许任何程序码使用
  • private(私人):只允许相同类别内的程序码使用
  • protected(保护):只允许相同类别及子类别的程序码使用

这就好像一个公司里,有全公司员工都知道的公司规定(public),有只有管理员知道的机密(private),也有同一个部门和他的上级主管才知道的资讯(protected)。

继承性(Inheritance)

是一种将软件再利用的形式,会在建立新类别时吸收现有类别的成员,再新增或修改功能。透过继承可以节省程序开发的时间,也可以提升有效实作及维护系统的可能性。

在建立类别时,可以指定新类别(子类别)去继承现有类别(父类别)的成员,每个子类别也有可能成为未来其他人的父类别,彼此是相对的关系。

Java 中的每个类别都继承自 Object,要注意的是 Java 只支援「单向继承」,意思是说一个子类别只可以有一个父类别,但一个父类别可以被多个子类别继承。

假设今天你是动物园管理员,要统整各动物的特性。这时候先以 Animal 当作父类别,Sheep 透过(extends)继承了 Animal,但除了 Aniaml 的 name 以外,还多了 woolColor 的属性,除此之外,也覆写(override)了 move 方法。

public class Zoo{
    public static void main(String[] args){
        Sheep s1 = new Sheep("绵羊1号","黑色");
        Sheep s2 = new Sheep();
        s2.setName("绵羊2号");
        s2.setWoolColor("白色");
        System.out.println(s1.getWoolColor() + s1.getName() + s1.move(10));
        System.out.println(s2.getWoolColor() + s2.getName() + s2.move(5));
    }
}

class Animal{
    private String name;
    
    public Animal(){

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

    public String move(int units){
        return "移动" + units + "步";
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

class Sheep extends Animal{
    private String woolColor;

    public Sheep(){
        super();
    }

    public Sheep(String name, String woolColor){
        super(name);
        this.woolColor = woolColor;
    }

    public void setWoolColor(String woolColor){
        this.woolColor = woolColor;
    }

    public String getWoolColor(){
        return woolColor;
    }

    @Override
    public String move(int units){
        return "跑" + units + "步";
    }
}
黑色绵羊1号跑10步
白色绵羊2号跑5步

我们可以看到呼叫 super() 会用来建构父类别,但其实如果不写的话 Java 也会自动呼叫,但是若是有带参数(像是 super(name))就必须自行撰写。

若我们今天将 Animal 里的方法从 public 改为 protected,则那些方法一样可以被 Sheep 存取,但是与 Animal 无关的类别(假设有另一个类别为 Vehicle)则无法存取。

覆写(Override)

还记得我们介绍过的「多载」吗?不记得的话可以回去看 Day10,接着要介绍的是英文名字和多载很像的「覆写」,上面的范例就是覆写的应用,但是覆写时必须满足几个限制:

  1. 父类别方法不能用 final 修饰

    有些值(像是 Pi),宣告完不需要再修改,为了防止遭到更动,在宣告时他的实体变数就是 final,例如:

    public final int PI;
    
  2. 子类别的方法名称、回传型态、参数个数需相同

    方法名称和回传型态如果不同的话,那就不是覆写了!参数个数不同的话那就是多载了!

  3. 子类别覆写的方法,其开放权限不可小於父类别的方法

    存取修饰子的开放权限:public > protected > private

今天就先到这里,是不是觉得这些特性很实用呢?尤其当你的程序非常大或是由多人撰写而成时,最後的多型性就留到明天了,可以再试着想想看生活中有哪些东西有继承的关系哦!


<<:  Day14 资料汇入和汇出

>>:  Day07-流量限制(二)

[C#] Base64 Convert.ToBase64String 基本转码及适用网址参数转码延伸应用

这次示范一个 C# 内将字串转为 Base64 字串的语法,并利用此转换方法延伸到适用网址上传递参数...

Day 16. 常见模板 Template App Apache / Nginx by Zabbix agent 介绍

Hi 大家今天要跟大家介绍 App 样板,主要是 Web 服务。 我们主要的服务都是基本上都是 LA...

Day 22 - 实战演练 — Portal 系列

实作第二篇要来介绍的是 Portal 系列的实作,会一路从 Portal 实作到 Popconfi...

【Day 05】领域驱动设计的启动

观察的视角 我们要如何描述一个系统呢? 可以从不同的角度观察,好比瞎子摸象,你摸到甚麽部位,系统就像...

轻松小单元 -工具篇

超连结真是伟大的发明,骗字数都靠他了 应办事项 软件名称 说明 网址 GCB LGPO 微软推出的 ...