程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java中的封裝、承繼、多態

Java中的封裝、承繼、多態

編輯:關於JAVA

Java中的封裝、承繼、多態。本站提示廣大學習愛好者:(Java中的封裝、承繼、多態)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中的封裝、承繼、多態正文


封裝

在如何了解面向對象這篇文章中,提到所謂的封裝就是“功用都給你做好了,你不用去了解它是怎樣寫出來的,直接運用即可。”。但你得清楚一點,那就是這句話是絕對於運用者來說的,而作為開發者,封裝就得我們自己來干。

那麼作為開發者,我們應該如何去封裝呢?其實你應該反過去問,他們應該如何去運用,這樣一想會復雜很多,作為運用者,自然是希望越復雜越好,也就是說,一些復雜的東西,我們不應該讓運用者去操作,那也就是說我們應該把復雜的,以及不用要的參數給它封死,不讓運用者去操作。

為什麼不讓運用者去操作?

由於往往運用者是不太專業的,假如暴露太多的接口給他們,就很有能夠呈現一些稀罕乖僻的問題,好比一個不會做水煮魚的,假如讓他去做那一定是不好的,那怎樣辦,給他買一包水煮魚的調料,讓他直接放進鍋裡就好,這樣就增加了不用要的費事。我們封裝順序也是這樣,把復雜的代碼封死,不讓操作者去操作,以免出錯。

比方上面這個例子:

class Average{
    private int[] fractions = new int[3]; //分數
    private int average = 0; //均勻分
    public void setFraction(int[] fraction){
        fractions = fraction;
    }
    public double getAverage(){
        for(int cell:fractions){
            average += cell;
        }
        return (double) average / fractions.length;
    }
}

class app{
    public static void main(String[] args){
        int[] a = {50,40,50};

        Average average = new Average();
        average.setFraction(a); //設置分數
        double n = average.getAverage(); //獲取均勻分
        System.out.println(average.average); //報錯
        System.out.println(n); //46.0
    }
}
提示:Java經過private設置公有變量,經過public將變量設置成地下的。

這裡我們之所以將分數戰爭均分設置成公有變量是為了避免運用者誤操作,而且也不用讓運用者知道有這麼一個變量,只需求讓運用者知道怎樣去設置分數,和獲取均勻分就好了。

當然這只是一個很根底的封裝,假如想封裝出一個好的順序,還得多費一些心思。

承繼

拿貓和狗來說,它們都是植物,而且它們有一些共同點,比方:名字,年齡,聲響,吃等。把這段話寫成代碼就是上面這個樣子。

class Animal{
    private String name;
    private int age;

    public void setName(String name){
        this.name = name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
}

class Cat extends Animal{
    public void voice(){
        System.out.println(super.getName() + " 喵");
    }
    public void eat(){
        System.out.println(super.getName() + " fish");
    }
}

class Dog extends Animal{
    public void voice(){
        System.out.println(super.getName() + " 汪");
    }
    public void eat(){
        System.out.println(super.getName() + " Bone");
    }
}

class app{
    public static void main(String[] args){
        Cat cat = new Cat();
        cat.setName("貓大王"); //Cat自身沒有setName辦法,但是它的基類有,所以java解析器會到Cat的基類那裡拿
        cat.voice();

        Dog dog = new Dog();
        dog.setName("大黑");
        dog.setAge(13);
        dog.voice();
        System.out.println(dog.getName() + dog.getAge());
    }
}

------Output------
貓大王 喵
大黑 汪
大黑13
提示:Java經過extends關鍵字來完成承繼,父類中經過private定義的變量和辦法不會被承繼,也就是你不能在子類中直接操作父類經過private定義的變量以及辦法。

在下面代碼中,我們可以看到,CatDog並沒有定義setNamesetAgegetNamegetAge辦法,但是我們仍然可以在CatDog類中運用,這是由於我們經過extends關鍵字承繼了Animal類,因而在Animal中定義的變量和辦法,我們可以在子類中直接運用,除private定義的變量和辦法。

反過去說,姓名和年齡是貓和狗的根本信息也是它們的共同特性。

重寫父類辦法或變量

普通重寫父類辦法,是由於你把貓當成是一個基類,而將狗承繼自貓類。看似這很好笑,但假如你去翻翻你的代碼,這種狀況多如牛毛。當然,假如你不需求承繼,那就另說了。那麼假如碰到這種狀況,我們怎樣重寫基類呢?很復雜,在子類中定義一個和父類中一樣的辦法,如上面這樣:

class Animal{
    private String name;
    private int age;

    public void setName(String name){
        this.name = name;
    }
    public void setAge(int age){
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
}

class Dog extends Animal{
    public String getName(){
        return super.getName() + "2";
    }
    public void voice(){
        System.out.println(super.getName() + " 汪");
    }
    public void eat(){
        System.out.println(super.getName() + " Bone");
    }
}

class app{
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.setName("大黑");
        System.out.println(dog.getName()); //執行的是Dog中的getName辦法
    }
}
提示:經過super可以在子類中直接調用父類的辦法以及變量,經過this調用以後類。

我覺得把這叫做重寫不太好,由於假如從實質來講,它不算重寫,只是Java尋覓變量以及辦法的規則罷了。Java會先看一下,自己身上有沒有某個變量或辦法,假如沒有,它會接著到父類中找,假如父類中還是沒有,那麼它又會到更上一級中找,假如不斷找上去都沒有,那麼才報錯。

在重寫父類時,需求留意一下,重寫時,辦法的前往值類型必需和父類中定義的分歧,比方上面這樣就會報錯

class Animal{
    private String name;

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
}
class Dog extends Animal{
    public int getName(){ //和父類中的getName前往值不同,報錯
        return 123;
    }
}

class app{
    public static void main(String[] args){
        Dog dog = new Dog();
        System.out.println(dog.getName());
    }
}

另外還需求留意,假如重寫時,和父類中的參數不分歧,則會發作意想不到的事,比方上面這個

class Animal{
    private String name;

    public void setName(String name){
        this.name = name;
    }
    public String getName(String hello){
        return this.name + hello;
    }
}

class Dog extends Animal{
    public String getName(){
        return "123";
    }
}

class app{
    public static void main(String[] args){
        Dog dog = new Dog();
        dog.setName("大黑");
        System.out.println(dog.getName("hello"));
    }
}

------Output------
大黑hello

可以看到當我們給getName傳達了參數時,執行的是Animal中的辦法,而非Dog中的getName辦法,也就是說假如參數不分歧最後執行的能夠就不是重寫的那個辦法。另外也不可將父類地下的辦法或變量改成公有(如將public改成private),否則也會報錯,我估量是Java有一套掩蓋規則,假如沒有到達條件就不會停止掩蓋。

多態

先來幾個例子,再講實際

class Animal{
    public int age = 5;

    public int getAge(){
        return age;
    }
    
}

class Dog extends Animal{
    public int age = 8;

    public int getAge(){
        return age + 2;
    }
}

class app{
    public static void main(String[] args){
        Animal dog = new Dog();
        System.out.println(dog.age);
    }
}
------Output------
5

Animal dog = new Dog();這麼一句話,可以發現它們的類型並不一樣,但卻可以正常運轉,之所以可以運轉是由於,Dog類是Animal的子類,而父類是包括子類的。我們說植物,那麼狗是不是就是植物中的一員呢,這是一定的,而這裡之所以假如運轉也正是這個理。

不過需求留意一下,經過這種方式創立的對象,在獲取實例變量時,獲取到的是父類中的實例變量,假如是辦法,則看子類中能否存在和父類中同名的辦法,假如存在則運用子類中的辦法,但是假如子類中有某個辦法,而父類中沒有,那麼就會報錯。如下這段代碼就會報錯

class Animal{
    public int age = 5;

    public int getAge(){
        return age;
    }
    
}

class Dog extends Animal{
    public int age = 8;

    public int getAge(){
        return age + 2;
    }
    public setAge(int a){
        this.age = a;
    }
}

class app{
    public static void main(String[] args){
        Animal dog = new Dog();
        System.out.println(dog.setAge(5));
    }
}

由於父類中沒有setAge這個辦法,因而會報錯。

也就是說,經過這種方式來寫,只能到達掩蓋辦法的效果,沒有其他的功用。

這裡所謂的多態,在順序中你可以了解成,一個辦法,它可以有不同的效果,那怎樣完成不同的效果呢?在java中經過切換類型來完成(不一定正確)。

多態有什麼用?

還是再來看幾個例子吧

class Animal{
    public int age = 5;

    public int getAge(){
        return age;
    }
    
}

class Dog extends Animal{
    public int getAge(){
        return age + 2;
    }
}

class Cat extends Animal{
    public int getAge(){
        return age + 3;
    }
}

class app{
    public static void main(String[] args){
        Animal dog = new Dog();
        Animal cat = new Cat();

        System.out.println(dog.getAge());
        System.out.println(cat.getAge());
    }
}
------Output------
7
8

可以看到,它會依據本身執行不同的辦法。不過話說回來,這並不能代表什麼,畢竟我們依照正常狀況來創立,效果也可以一樣,不過還真有它的用武之處,比方上面這段代碼

class Animal{
    public int age = 5;

    public int getAge(){
        return age;
    }
    
}

class Dog extends Animal{
    public int getAge(){
        return age + 2;
    }
}

class Cat extends Animal{
    public int getAge(){
        return age + 3;
    }
}

class app{
    public static void main(String[] args){
        Animal[] animals = new Animal[2];
        animals[0] = new Dog();
        animals[1] = new Cat();

        System.out.println(animals[0].getAge());
        System.out.println(animals[1].getAge());
    }
}
------Output------
7
8

這段代碼和下面一段差不多,不過這段代碼中用的是一個數組,這種狀況就比擬合適運用多態了,不然仿佛沒有其他方法來弄了吧(初學java,不太懂)。在這外面多態不只僅只是指一個辦法有不同的效果,在這裡還指類型的多樣性。

好了就到這裡了。

引薦閱讀

Java中函數的重載和重寫


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved