this
趙本山問奧尼爾:“我的爸爸的爸爸是誰?”
奧尼爾:“不知道”
趙本山:“你傻啊,是我爺爺”
奧尼爾回去問科比:“我的爸爸的爸爸是誰?”
科比:“不知道”
奧尼爾:”你傻啊,是趙本山的爺爺“
就像這個笑話一樣,不同的人,用this時,指向的對象也是變的。
普通方法中,this總是指向調用該方法的對象
//this在成員方法中的用處 //this就是指代當前對象,是一個隱式參數 public class thissss { public static void main(String []args) { Student s1 = new Student(); s1.name = "小白"; s1.age = 17; s1.study(); System.out.println(s1.name); Student s2 = new Student(); s2.name = "小徐"; s2.age = 18; s2.study(); } } class Student { int age; String name; public void study() //在創建成員方法(函數)的時候會自動傳一個this參數,指向該對象的地址,但是是隱藏的 { this.name = "小黑"; //s1.name = "小黑"; //這條語句是錯誤的,因為對象要在類創建完成之后才有 //但是使用this.name就可以給類進行賦值 //因為this指向創建的對象的地址,所以this.name就會找到該對象中study()方法的地址 //對這個地址進行操縱,總而更改當前對象的值 System.out.println(name+"在學習"); } }
圖解:
構造方法中,this總是指向正要初始化的對象
//this在構造方法中的用處 //用來指向正在初始化的對象 public class thissss2 { public static void main(String []args) { Student s1 = new Student(17); System.out.println(s1.age); Student s2 = new Student(18); } } class Student { int age; String name; public Student(int age) { //age = age //直接寫age指代的是public void Student(String name,int age)傳進來的name,就近原則 //this.age指代的是當前正在初始化的對象中的String age; this.age = age; } } 輸出結果: age = age時,輸出的是0,並非是正常的結果 this.age = age時,輸出的是正常的結果17
原因也是因為會默認傳一個this參數,用來指向當前使用這條命令的對象的地址,這樣就可以正確的初始化當前對象中成員變量的值了
注意:this不能用於static方法(學了static方法就知道為什么了)
變量的種類
實例變量、類變量、常量都是屬於成員變量的,成員變量又被稱為全局變量
public class A{ String id; //實例變量 private String Tel; //實例變量 private int size; //實例變量 private static String depart; //類變量 final String design="樣式"; //常量 } /*其中實例變量、類變量、常量都是屬於成員變量的,成員變量又被稱為全局變量, 成員變量的范圍比實例變量更寬泛 */
方法(函數)的種類
實例方法(instance method):或叫成員方法(member method)。供實例用的方法,必須要先有實例,才能通過此實例調用實例方法。
靜態變量 / 類變量
提問:有一群小孩在玩堆雪人,不時有新的小孩加入,請問如何知道現在有多少人在玩呢?請使用面向對象的思想,編程解決。

1 public class Demo1 2 { 3 public static void main(String []args) 4 { 5 int total = 0; 6 Child ch1 = new child(3,"小徐"); 7 ch1.joinGame(); 8 total++; 9 10 Child ch2 = new child(4,"小白"); 11 ch2.joinGame(); 12 total++; 13 //查看總人數的時候,只需要輸入total的值就可以了 14 //但是要求是使用面向對象的方法,課時這個total並沒有封裝到對象中去 15 } 16 } 17 18 //定義kid類 19 class Child 20 { 21 int age; 22 String name; 23 public Child(int age,String name) 24 { 25 this.age = age; 26 this.name = name; 27 } 28 public void joinGame() 29 { 30 System.out.println("有一個小孩加入了"); 31 } 32 }
從上面的例子中可以看到,要是有一個所有對象都能操作的變量就好了,而java中確實有這個變量,叫做靜態變量(也叫類變量)

public class Demo1 { public static void main(String []args) { Child ch1 = new Child(3,"小徐"); ch1.joinGame(); Child ch2 = new Child(4,"小白"); ch2.joinGame(); System.out.println("公有="+ch2.total); //也可以直接用類訪問靜態變量 System.out.println("公有="+Child.total); } } //定義kid類 class Child { int age; String name; //total是靜態變量, 因此可以被任何一個對象訪問 static int total = 0; public Child(int age,String name) { this.age = age; this.name = name; } public void joinGame() { total++; //在這里進行計數操作 System.out.println("有一個小孩加入了"); } }
什么是:靜態變量(類變量)?
類變量是該類的所有對象的共享變量,任何一個該類的對象去訪問它是,取到的都是相同的值,同樣任何一個該類的對象去修改它時,修改的也是同一個變量。
靜態變量的定義語法
訪問修飾符 static 數據類型 變量名;
靜態變量的訪問方法
- 類名 . 靜態變量名
- 對象名 . 靜態變量名
加深靜態方法的理解的小例子

1 public class Demo2 2 { 3 static int i=1; 4 static //靜態區域塊只會被執行一次 5 { 6 i++; 7 } 8 public Demo2() 9 { 10 i++; 11 } 12 13 public static void main(String []args) 14 { 15 Demo2 t1 = new Demo2(); 16 System.out.println(t1.i); 17 Demo2 t2 = new Demo2(); 18 System.out.println(t2.i); 19 20 } 21 }
原理:

1 public class Demo2 2 { 3 static int i=1; 4 static //靜態區域塊只會被執行一次 5 { 6 i++; 7 System.out.println("靜態區域塊"); 8 } 9 public Demo2() 10 { 11 i++; 12 System.out.println("成員方法Demo2"); 13 } 14 15 public static void main(String []args) 16 { 17 Demo2 t1 = new Demo2(); 18 System.out.println(t1.i); 19 Demo2 t2 = new Demo2(); 20 System.out.println(t2.i); 21 22 } 23 } 24 25 輸出結果: 26 靜態區域塊 27 成員方法Demo2 28 3 29 成員方法Demo2 30 4
不創建對象static也會執行,原理將來會講

public class Demo2 { static int i=1; static //靜態區域塊只會被執行一次 { i++; System.out.println("靜態區域塊"); } public Demo2() { i++; System.out.println("成員方法Demo2"); } public static void main(String []args) { } } 輸出結果: D:\myJavaDemo\Day3>java Demo2 靜態區域塊
靜態方法(類方法)
小例子:
public class Demo3 { public static void main(String []args) { //創建一個學生 Stu stu1=new Stu(29,"aa",340); Stu stu2 = new Stu(29,"aa",290); System.out.println(stu2.getTotalFee()); //此時這個語法是有歧義的,感覺輸出的是stu2的學費,但是輸出的是所有學生的費用 } } class Stu { int age; String name; int fee; static int totalFee; public Stu(int age,String name,int fee) { this.age = age; this.name = name; totalFee+=fee; } public int getTotalFee() { return totalFee; } }
使用靜態方法
java中有一個規則,靜態變量原則用靜態方法去訪問和操作,約定俗成的。並且
- 靜態方法中不能對非靜態變量操作
- 但普通的成員方法可以操作靜態變量,
- 靜態變量都可以被操作,非靜態方法不能被靜態方法操作

1 public class Demo3 2 { 3 public static void main(String []args) 4 { 5 //創建一個學生 6 Stu stu1=new Stu(29,"aa",340); 7 Stu stu2 = new Stu(29,"aa",290); 8 //可以直接使用Stu類名來訪問這個靜態方法 9 System.out.println(Stu.getTotalFee()); 10 11 } 12 } 13 14 class Stu 15 { 16 int age; 17 String name; 18 int fee; 19 static int totalFee; 20 21 public Stu(int age,String name,int fee) 22 { 23 this.age = age; 24 this.name = name; 25 totalFee+=fee; 26 } 27 public static int getTotalFee() //區別就是這條語句中多了一個static 28 { 29 return totalFee; 30 } 31 }
什么時候使用靜態方法?
如果有一個方法(函數)需要讓所有的對象去共享的時候,就可以設計成為靜態方法
靜態方法的語法
訪問修飾符 static 數據返回類型 方法名 () { //語句; } //注意靜態方法中不能訪問非靜態變量,例如: 成員屬性
使用方法
類名 . 靜態方法名 對象名 . 靜態方法名
類變量與實例變量的區別
靜態變量(類變量) int a; String name; 實例變量 int static a; String static name;
- 加上static稱為靜態變量或類變量 ,否則稱為實例變量
- 類變量是與類相關的,公共的屬性
- 實例變量是屬於每個對象個體的屬性
- 類變量可以通過 類名.類變量名 直接訪問
靜態方法(類方法)與實例方法的區別
靜態方法(類方法) public static int getTotalFee() { return totalFee; } 實例方法 public int getTotalFee() { return totalFee; }
- 類方法屬於與類相關的,公共的方法
- 實例方法屬於每個對象個體的方法
- 類方法可以通過 類名.類方法名 直接訪問
四大特征——抽象、封裝、繼承、多態
一般是說java有三大特征,即封裝、繼承、多態。但有人也會把抽象算進去,如順平
抽象
我們前面在定義一個類的時候,實際上就是把一類事物共有的屬性和行為提取出來,形成一個物理模型(模板)。這種研究問題的方法稱為抽象。
封裝
封裝就是把抽象出的數據和對數據的操作封裝在一起,數據被保護在內部,程序的其它部分只有通過被授權的操作(成員方法),才能對數據進行操作。
就像電視機一樣,電路板被保護在內部,我們不能直接操作電路板,但是我們可以通過電視機上的按鈕來的操作電路板,從而達到我們的目的。
訪問控制修飾符
小例子:訪問公有的成員變量

1 public class Demo4 2 { 3 public static void main(String []args) 4 { 5 Clerk clerk1 = new Clerk("小花",24,4567.6f); 6 System.out.println("名字是"+clerk1.name); 7 8 } 9 } 10 11 class Clerk 12 { 13 public String name; //public共有的 14 private int age; //private私有的 15 private float salary; 16 17 public Clerk(String name,int age,float sal) 18 { 19 this.name = name; 20 this.age = age; 21 this.salary = sal; 22 } 23 } 24 25 輸出結果: 26 名字是小花
但訪問私有的成員變量時,會報錯

1 public class Demo4 2 { 3 public static void main(String []args) 4 { 5 Clerk clerk1 = new Clerk("小花",24,4567.6f); 6 System.out.println("名字是"+clerk1.name); 7 8 } 9 } 10 11 class Clerk 12 { 13 public String name; //public共有的 14 private int age; //private私有的 15 private float salary; 16 17 public Clerk(String name,int age,float sal) 18 { 19 this.name = name; 20 this.age = age; 21 this.salary = sal; 22 } 23 } 24 25 報錯信息: 26 Demo4.java:11: 錯誤: salary 在 Clerk 中是 private 訪問控制 27 System.out.println("薪水是"+clerk1.salary); 28 ^ 29 1 個錯誤
通過成員方法去控制和訪問私有的屬性

1 public class Demo4 2 { 3 public static void main(String []args) 4 { 5 Clerk clerk1 = new Clerk("小花",24,4567.6f); 6 System.out.println("薪水是"+clerk1.getSal()); 7 8 } 9 } 10 11 class Clerk 12 { 13 public String name; //public共有的 14 private int age; //private私有的 15 private float salary; 16 17 public Clerk(String name,int age,float sal) 18 { 19 this.name = name; 20 this.age = age; 21 this.salary = sal; 22 } 23 //通過一個成員方法去控制和訪問私有的屬性 24 public float getSal() 25 { 26 return this.salary; 27 } 28 } 29 30 輸出結果: 31 薪水是4567.6
因為成員方法是公開的(public),可以被使用。
就像我們使用電視機的時候不能通過操作電路板來換台、調節音量,但是我們可以通過操作電視機給我們提供的按鈕來進行換台、調節音量的操作。電視機上的按鈕就相當於成員方法。
- 廠商不讓我們操作電路板,但是讓我們操作按鈕來間接操作電路板。
- 類不讓我們訪問私有的屬性,但是讓我們使用成員方法來訪問私有屬性。
Java提供四種訪問控制修飾符號 控制 方法和變量 的訪問權限
- 公開級別:用 pulic 修飾,對外公開
- 受保護級別:用 protected 修飾,對子類和同一個包中的類公開
- 默認級別:沒有修飾符號,像同一個包的類公開
- 私有級別:用 private 修飾,只有類本身可以訪問,不對外空開
包
從包開始,就不用記事本寫程序了,改成用eclipse了
包的必要性?
有這樣的一種情況,小白定義了一個類取名為Dog,賽拉也定義了一個類取名為Dog,然后他們倆就打起來了。我們使用myeclipse來模擬一下這種情況
小徐此時站了起來,說:“你們是傻嗎?不知道包的作用!”
.代表再分一層
包的作用
- 區分相同名字的類
- 當類很多時,可以很好的管理
- 控制訪問范圍
打包命令
命令一般放在文件開頭的地方
package com.shunping; //這條命令會自動生成,會自動把字節碼放到com.shunping這個包中去
命名規范
//包名都是小寫字母 , 用 . 隔開 , 比如 com.sina.shunping
常用的包
一個包下,包含很多的類,java中常用的包有:
- java.lang.* —— 這個包是自動引入的
- java.util.* —— 工具包
- java.net.* —— 網絡開發包
- java.awt.* —— 窗口工具包
引入一個包
語法 : import 包; import java.awt.* ;
我們引入一個包的主要目的是使用該包下的類
用包來控制訪問范圍

1 package com.xiaoqiang; 2 3 public class Test 4 { 5 public static void main(String[] args) 6 { 7 Dog dog1 = new Dog(); 8 9 //驗證同包下的權限訪問情況 10 System.out.println(dog1.a); 11 12 } 13 14 } 15 class Dog 16 { 17 public int a; 18 protected String name; 19 String color; 20 private float price; 21 22 //驗證同類下的權限訪問情況 23 public void ab1() 24 { 25 System.out.println(this.a); 26 27 } 28 }
同類下的訪問權限
同包下的訪問權限——沒有私有屬性的price類
不同包下的訪問權限用——用小明去訪問小強中的Dog類
在小強的包下新建一個公有的Cat類,里面的內容和Dog相同,此時小明的訪問情況為

1 package com.xiaoqiang; 2 3 public class Cat 4 { 5 public int a; 6 protected String name; 7 String color; 8 private float price; 9 10 public void ab1() 11 { 12 System.out.println(this.a); 13 14 } 15 }
權限訪問情況為——只能訪問公有類
如果我就是想訪問其它的屬性呢?
——這時就要用到封裝的思想,用公有的成員方法去訪問私有屬性

1 package com.xiaoqiang; 2 3 public class Cat 4 { 5 public int a; 6 protected String name; 7 String color; 8 private float price; 9 10 //提供一個訪問name的成員方法 11 public String getName() 12 { 13 return this.name; 14 15 } 16 17 18 }
繼承
為什么有繼承?
小例子:我們定義小學生,中學生,大學生類

1 public class Demo 2 { 3 public static void main(String[] args) 4 { 5 } 6 7 } 8 9 //小學生類 10 class Pupil 11 { 12 //定義成員屬性 13 private int age; 14 private String name; 15 private float fee; 16 17 //交費 18 public void pay(float fee) 19 { 20 this.fee = fee; 21 } 22 } 23 24 //中學生類 25 class MiddleStu 26 { 27 //定義成員屬性 28 private int age; 29 private String name; 30 private float fee; 31 32 //交費 33 public void pay(float fee) 34 { 35 this.fee = fee*0.8f; 36 } 37 } 38 39 //大學生類 40 class ColStu 41 { 42 //定義成員屬性 43 private int age; 44 private String name; 45 private float fee; 46 47 //交費 48 public void pay(float fee) 49 { 50 this.fee = fee*0.1f; 51 } 52 }
繼承就可以很好的解決代碼重復問題,讓我們的編程更加靠近人類的思維。
當多個類中存在相同的屬性(變量)和方法時,可以從這些類中抽象出父類,在父類中定義這些相同的屬性和方法。這樣所有的子類不需要重新定義這些屬性和方法,只需要通過extends語句來把父類的這些屬性和方法繼承過來就行。

1 public class Demo 2 { 3 public static void main(String[] args) 4 { 5 } 6 7 } 8 //將學生的共有屬性抽象出來, 做一個父類 9 class Student 10 { 11 public int age; 12 public String name; 13 public float fee; 14 15 } 16 //小學生類 17 class Pupil extends Student{ 18 //交費 19 public void pay(float fee) 20 { 21 this.fee = fee; 22 } 23 } 24 //中學生類 25 class MiddleStu extends Student{ 26 //交費 27 public void pay(float fee) 28 { 29 this.fee = fee*0.8f; 30 } 31 } 32 //大學生類 33 class ColStu extends Student{ 34 //交費 35 public void pay(float fee) 36 { 37 this.fee = fee*0.1f; 38 } 39 }
繼承的語法
class 子類 extends 父類 ; //這樣子類就會自動擁有父類定義的某些屬性和方法,有些東西是繼承不了的
深入探討——父類的哪些屬性(變量)、方法被子類繼承了
父類: { public int a; protected int b; int c; private int d; public int getA(){} protected int getB(){} int getC(){} private int getD(){} } ————————————繼承———————————— 子類: { public int a; protected int b; int c; public int getA(){} protected int getB(){} int getC(){} }
可以看出只有private修飾符的屬性和方法不能被子類繼承,所以不希望子類繼承的屬性和方法,只需要把那個屬性和方法設置為private屬性即可
繼承的注意事項
- 子類最多只能繼承一個父類(指直接繼承),可以通過接口進行多重繼承 ,之后會講
- java所有類都是Object類的子類
- JDK6中有202個包,3777個類、接口、異常、枚舉、注釋和錯誤,掌握150個就是大神了
- 在做開發的時候,強烈建議大家多查jdk幫助文檔,還是不會就google

import javax.swing.*; public class Demo2 extends JFrame { public static void main(String[] args) { Demo2 demo2 = new Demo2(); } public Demo2() { this.setVisible(true); this.setSize(200 , 200); } }
如果不使用繼承的話,需要調用一些復雜的命令
方法重載
在多態前要先了解一下方法重載(overload)和方法覆蓋(override)
思考一下:編寫一個名為Abc的類,能返回兩個整數中較大的一個
- 若果是接收兩個float型的數,返回較大數
- 如果是接收散了int型的數,返回最大數

1 public class Demo3 { 2 public static void main(String[] args) { 3 Abc test1 = new Abc(); 4 System.out.println(test1.getMax(23, 78)); 5 } 6 7 } 8 9 class Abc 10 { 11 public int getMax(int i,int j) 12 { 13 if(i>j) 14 { 15 return i; 16 } 17 else 18 { 19 return j; 20 } 21 } 22 }

1 public class Demo3 { 2 public static void main(String[] args) { 3 Abc test1 = new Abc(); 4 Abc test2 = new Abc(); 5 System.out.println(test1.getMax(23, 78)); 6 System.out.println(test1.getMaxFloat(9.8f, 12.2f)); 7 } 8 9 } 10 11 class Abc 12 { 13 public int getMax(int i,int j) 14 { 15 if(i>j) 16 { 17 return i; 18 } 19 else 20 { 21 return j; 22 } 23 } 24 public float getMaxFloat(float a,float b) 25 { 26 if(a>b) 27 { 28 return a; 29 } 30 else 31 { 32 return b; 33 } 34 } 35 }
可以看出我們是又專門加一個,比較小數的成員方法,有沒有方法用一個方法來進行比較呢?
這個時候有可以利用方法重載的特性——可以定義重名的兩個成員方法,讓編譯器自己選擇用哪個?

1 package com.xiaohui; 2 /* 3 * 作者:我聊啊 4 * 時間:2018.9.11 5 * 功能:了解方法重載 6 */ 7 public class Demo3 { 8 public static void main(String[] args) { 9 Abc test1 = new Abc(); 10 Abc test2 = new Abc(); 11 System.out.println(test1.getMax(23, 78)); 12 System.out.println(test1.getMax(9.8f, 12.2f)); 13 } 14 15 } 16 17 class Abc 18 { 19 public int getMax(int i,int j) 20 { 21 if(i>j) 22 { 23 return i; 24 } 25 else 26 { 27 return j; 28 } 29 } 30 public float getMax(float a,float b) 31 { 32 if(a>b) 33 { 34 return a; 35 } 36 else 37 { 38 return b; 39 } 40 } 41 }
方法重載的概念
簡單地說:方法重載就是在類的同一種功能的多種實現方式,到底使用哪種方式,取決於調用者給出的參數。
注意事項
- 方法名一定相同
- 方法的參數類型,個數,順序至少有一項不同——(順序:(int a , double b)改成(double a , int b))
- 返回類型也可以不相同,但是如果只有返回類型不一樣,是不能夠構重載的
- 方法的訪問控制修飾符可以不同,如果只是修飾符不同,也是不能夠構成重載的
方法的覆蓋(重寫)
既然子類可以繼承父類的屬性和方法,這樣可以提高代碼的復用性,這個很好,可是問題來了!!
假設我要寫三個類——貓、狗、豬,顯然這三個都是動物,他們之間一定存在着相同的特點。根據類的抽象特征,我們可以把他們的相同點提取出來,形成一個父類Animal,然后繼承。
但是問題來了,動物都會叫,但是叫聲是不一樣的,怎樣解決子類和父類方法的異同!
這是就體現出了方法覆蓋(重寫)的特性了

1 public class Demo4 2 { 3 public static void main(String[] args) { 4 Cat cat1 = new Cat(); 5 cat1.cry(); 6 7 Dog dog1 = new Dog(); 8 dog1.cry(); 9 } 10 11 } 12 13 class Animal 14 { 15 int age; 16 String name; 17 //動物都會叫 18 public void cry() 19 { 20 System.out.println("我是動物,不知道怎么叫"); 21 } 22 } 23 class Cat extends Animal 24 { 25 //覆蓋了父類的方法 26 public void cry() 27 { 28 System.out.println("喵喵喵"); 29 } 30 } 31 32 class Dog extends Animal 33 { 34 //覆蓋了父類的方法 35 public void cry() 36 { 37 System.out.println("汪汪汪"); 38 } 39 }
方法重寫的核心思想:子類的某些方法和父類不一樣,需要覆蓋掉父類的方法
方法覆蓋的概念
簡單的說:方法覆蓋就是子類有一個方法,和父類的某個方法的名稱、返回類型、參數一樣,那么我們就說子類的這個方法覆蓋了父類的那個方法。
注意事項
- 子類的方法的返回類型,參數,方法名稱要和父類方法的返回類型完全一致,否則編譯會出錯
- 子類方法不能縮小父類方法的訪問權限,換句話說子類的權限可以比父類高
多態
所謂多態,就是指一個引用(類型)在不同情況下的多種狀態。也可以這樣理解:多態是指通過指向父類的指針,來調用在不同子類中實現的方法
案例

1 public class Demo6 2 { 3 public static void main(String[] args) 4 { 5 //多態 6 Animal an;//創建了一個Animal類引用變量,Animal類引用就是以后可以用來指向Animal對象的對象引用 7 an =new Cat(); //讓這個動物的引用指向了貓這個實例(對象) 8 an.cry(); 9 an = new Dog(); 10 //以Dog類為模板,在堆空間里創建一個Dog類對象,簡稱為Dog對象 11 an.cry(); 12 //an這個引用會自動判斷引用是那種類型的 13 } 14 } 15 //動物類 16 class Animal 17 { 18 String name; 19 int age; 20 public String getName() { 21 return name; 22 } 23 public void setName(String name) { 24 this.name = name; 25 } 26 public int getAge() { 27 return age; 28 } 29 public void setAge(int age) { 30 this.age = age; 31 } 32 33 //動物會叫 34 public void cry() 35 { 36 System.out.println("不知道怎么叫"); 37 } 38 39 } 40 class Cat extends Animal 41 { 42 //貓自己叫 43 public void cry() 44 { 45 System.out.println("喵喵喵"); 46 } 47 } 48 class Dog extends Animal 49 { 50 //狗自己叫 51 public void cry() 52 { 53 System.out.println("汪汪汪"); 54 } 55 } 56 57 輸出結果: 58 喵喵喵 59 汪汪汪
如果沒有這個特性,狗要叫就要創建一個狗的引用,貓要叫就要創建一個貓的引用,動物再多一點就會不方便管理。當然多態也能調用孫子類的方法。

1 package com.xiaohui; 2 3 public class Demo7 4 { 5 public static void main(String[] args) 6 { 7 Master master = new Master(); 8 master.feed(new Dog(), new Bone()); 9 master.feed(new Cat(),new Fish()); 10 //我想要他喂那種動物就喂那種懂我,我想喂他吃什么就吃什么 11 // 12 } 13 14 } 15 //主人類 16 class Master 17 { 18 //給動物喂食物,使用多態,方法就可以用一個 19 public void feed(Animal an,Food f) 20 { 21 an.eat(); 22 f.showName(); 23 } 24 } 25 26 class Food 27 { 28 String name; 29 public void showName() 30 { 31 32 } 33 } 34 class Fish extends Food 35 { 36 public void showName() 37 { 38 System.out.println("魚"); 39 } 40 } 41 class Bone extends Food 42 { 43 public void showName() 44 { 45 System.out.println("骨頭"); 46 } 47 } 48 //動物類 49 class Animal 50 { 51 String name; 52 int age; 53 //動物會吃 54 public void eat() 55 { 56 System.out.println("不知道吃什么"); 57 } 58 } 59 60 class Cat extends Animal 61 { 62 //貓進食 63 public void eat() 64 { 65 System.out.println("貓愛吃魚"); 66 } 67 } 68 69 class Dog extends Animal 70 { 71 //狗進食 72 public void eat() 73 { 74 System.out.println("狗愛吃骨頭"); 75 } 76 }
如果Food類和Animal類下的子類有許多的話,Master類中的方法是無需改變的,只需要輸入對應的動物和事物就可以了。否則我們想要狗吃骨頭和貓吃魚就要用這么多的代碼來寫
Dog dog1 = new Dog(); dog1.eat(); Bone bone1 = new Bone(); bone1.showName(); Cat cat1 = new Cat(); cat1.eat(); Fish fish1 = new Fish(); fish1.showName();
引用的注意事項:
- Java允許父類的引用變量引用它的子類的對象(對象)
Animal animal = new Cat()
這種轉換是自動完成的
- 類型轉換還有一些具體的細節要求,之后會進一步學醫,比如子類能不能轉換成父類,有什么要求等等...