IT铁人DAY 3-物件导向基本概念(2)

  已经知道了类别与物件的差别以後,接下来就谈谈类别的方法该怎麽使用,以及物件导向的三大特性吧!


基本概念

方法(Method)

  简单来说,方法内定义了一个类别可以做的事情,有呼叫才会去执行,没呼叫则不会动作。我再举昨天的程序范例做说明:

class Employee {
    int ID;
    String name;
    int age;
    int depID;
    String depName;

    public Employee(int id, String name, int age) {    //此为建构子(Constructor)
        ID = id;
        this.name = name;
        this.age = age;
    }

    //以下为方法(Method)
    public void setDepartment(int depID, String depName) {
        this.depID = depID;
        this.depName = depName;
    }

    public String getEmployeeInfo() {
        return "员工编号:" + ID + " 员工姓名:" + name + " 员工年龄:" + age;
    }

    public String getDepartment() {
        return "部门编号:" + depID + " 部门名称:" + depName;
    }
}

public class Company {

    public static void main(String []args){

        Employee Jack = new Employee(123, "Jack", 45);
        Jack.setDepartment(12, "资讯部");
        System.out.println(Jack.getEmployeeInfo());

    }
}

//    result:
//        员工编号:123 员工姓名:Jack 员工年龄:45

  如上面的程序范例所示,我们宣告了Jack为员工类别以後,并呼叫了Jack的setDepartment()方法设定了depID与depName,然後再呼叫Jack的getEmployeeInfo()方法得到了Jack的基本资料把它印出来。

物件导向之三大特性

封装 (Encapsulation)

  其实封装已经在之前的范例呈现过了,不知道各位有没有看出来?以之前的例子来说,封装就是把一个类别所需要的资讯都包在一起,因此物件被创建以後,就不需要其他物件的帮忙,因为它本身已经拥有了运行操作所需要的资料。

  而封装这个特性带给了物件导向的程序减少耦合(Coupling),让程序内的物件不互相影响,那这块就比较偏系统分析了,就不多做说明,有兴趣的人可以去搜寻「耦合和内聚」。

  

继承(Inheritance)

  继承这项特性会使类别间有了父子关系,子类别可以使用父类别中的属性及方法,不过也不是全部都可以使用,端看於程序撰写时赋予的修饰符而定,有关修饰符的知识後面会讲解,现在请看以下范例程序码:

class Employee {
    protected int ID;
    protected String name;
    protected int age;

    public Employee(int id, String name, int age) {
        ID = id;
        this.name = name;
        this.age = age;
    }

    public String getEmployeeInfo() {
        return "员工编号:" + ID + " 员工姓名:" + name + " 员工年龄:" + age;
    }
}

class Engineer extends Employee {
	
    public Engineer(int id, String name, int age) {
        super(id, name, age);
    }

    public void job() {
        System.out.println("我的工作是写程序");
    }
}

public class Company {

    public static void main(String []args){
        Engineer Jack = new Engineer(123, "Jack", 30);

        System.out.println(Jack.getEmployeeInfo());
        Jack.job();
    }
}

//    result:
//        员工编号:123 员工姓名:Jack 员工年龄:30
//        我的工作是写程序

  我一样举员工这个类别做范例,但不一样的地方在於多了一个工程师类别,且继承了员工类别的属性与方法,所以我们宣告了Jack 是一个工程师,而工程师能够用 Employee内的getEmployeeInfo()方法,还有个特别的地方是 Engineer 的建构子内有一个 super(),而这个 super() 会去找 Engineer 的父类别(Employee),赋予其该有的属性,是不是很神奇呢!

  有了继承这个特性,就可以创造不同的类别,而这些类别之间又有相同的属性及方法,不需要重复写那些相同的功能;不过继承也是有它的缺点的,可以想到,既然子类别拥有父类别的方法,所以父类别只要修改,就会影响到子类别的实例,如果继承的子类别很多,整个程序的耦合就会很高,影响的范围就会很大。

多型(Polymorphism)

  多型这个特性是能够改写类别本身的方法,并且让两种以上的方法有相同的名称,但是所带的参数是不同的。那多型其实包含了多载(Overloading)和复写(Overriding)。

  那甚麽是多载(Overloading)呢?其实就是在相同的类别内,有两的相同名称的方法,但它们所需要的参数不一样,可能是参数个数不同,或是参数的型态不同,那只要利用方法之间所需要的参数差异,程序就可以呼叫到对应的方法,我们看以下程序范例:

class Employee {
    protected int ID;
    protected String name;
    protected int age;

    public Employee(int id, String name, int age) {
        ID = id;
        this.name = name;
        this.age = age;
    }
    //第一个方法
    public void job() {
        System.out.println("我的工作内容是写程序!");
    }
    //第二个方法
    public void job(String position) {
        System.out.println("我的职称是:" + position);
    }
}

public class Company {

    public static void main(String []args){
        Employee Jack = new Employee(123, "Jack", 30);

        Jack.job();
        Jack.job("工程师");
    }
}

//    result:
//        我的工作内容是写程序!
//        我的职称是工程师

  

  可以看到员工类别里面有两个同名的方法(job()),不过一个是不需带参数,一个是要带一个字串型态的参数,所以我们第一次呼叫没有带参数,程序对应到的是第一个方法,输出的结果就是「我的工作内容是写程序!」,而第二次我们带了一个「工程师」的字串,程序自动对到第二个方法去执行,输出结果为「我的职称是工程师」。

  再来讲甚麽是复写(Overriding),与多载的差异其实就只是复写他是发生在不同的类别,而这两个类别有继承关系,我们看以下程序范例:

class Employee {
    protected int ID;
    protected String name;
    protected int age;

    public Employee(int id, String name, int age) {
        ID = id;
        this.name = name;
        this.age = age;
    }

    public void selfIntrodution() {
        System.out.println("我的名子叫" + name + ",今年" + age + "岁!");
    }
}

class Engineer extends Employee {

    public Engineer(int id, String name, int age) {
        super(id, name, age);
    }

    public void selfIntrodution(String content) {
        System.out.println("我是一位" + content);
    }
}

public class Company {

    public static void main(String []args) {
        Engineer Jack = new Engineer(123, "Jack", 30);
                
        Jack.selfIntrodution();
        Jack.selfIntrodution("工程师");
    }
}

//    result:
//        我的名子叫Jack,今年30岁!
//        我是一位工程师

  

  程序中可以看到工程师类别子己也写了一个与父类别方法同名的方法(selfIntrodution()),那第一次呼叫的方法没有带参数,所以程序对应到的是父类别(Employee)的方法,输出的结果就是「我的名子叫Jack,今年30岁!」,而第二次我们带了一个「工程师」的字串,程序自动对到子类别(Engineer)本身的方法去执行,输出结果为「我是一位工程师」。

  相信看到这里,有些人对於这些特性已经很了解了,而有些人还是百思不得其解。没关系!因为我也没有看一次就学会的天赋,在大学时期第一次听完这些内容我也懵懵懂懂,不过还是要对自己所选的课程负责,反覆复习个几遍,这些特性就会刻在脑海里了。物件导向基本概念篇还没结束,我们下一篇见!


除此之外,也欢迎大家走走逛逛关於我们团队夥伴的文章
lu23770127 - SASS 基础初学三十天
10u1 - 糟了!是世界奇观!
juck30808 - Python - 数位行销分析与 Youtube API 教学
SiQing47 - 前端?後端?你早晚都要全端的,何不从现在开始?


<<:  Day4:如何使用Parrot_Security的CeWL工具收集特定网站的Wordlist

>>:  【Day3】 Cyber Kill Chain 与 MITRE ATT&CK

[Day3] 使用ta-lib制作指标

延续前一天的程序码,在程序码後面加上以下三行程序码,他就会用前一天做出来的日收盘价计算出均线(预设算...

[Day 28]TensorBoard介绍

聊了许多TensorFlow,不能不讲到TensorBoard啦!TensorBoard是Tenso...

自动化工作 - APScheduler

身为一个佛系投资人,最重要的就是排程了,让电脑不只会挑土豆,还会挑股票,今天介绍的是 Python ...

D13 - 做出鸡蛋糕 new + Constructor

前言 距离上次的你不知道 Combo 有段时间了,这次要端出的是营养更 up up 的满汉全席原型系...

Chapter4 - Canvas背景动画(IV)把纷飞的落叶,通通抓回来当作收藏吧!

今天挑战半小时写完一篇文章(被打,其实我写完程序了,把文章撰写出来就好噜。 https://jerr...