/* final能夠修飾類,方法,變量 特色: final能夠修飾類,該類不能被繼承。 final能夠修飾方法,該方法不能被重寫。(覆蓋,複寫) final能夠修飾變量,該變量不能被從新賦值。由於這個變量其實常量。 常量: A:字面值常量 "hello",10,true B:自定義常量 final int x = 10; */
/* 面試題:final修飾局部變量的問題 基本類型:基本類型的值不能發生改變。 引用類型:引用類型的地址值不能發生改變,可是,該對象的堆內存的值是能夠改變的。 */
/* 多態:同一個對象(事物),在不一樣時刻體現出來的不一樣狀態。 舉例: 貓是貓,貓是動物。 水(液體,固體,氣態)。 多態的前提: A:要有繼承關係。 B:要有方法重寫。 其實沒有也是能夠的,可是若是沒有這個就沒有意義。 動物 d = new 貓(); d.show(); 動物 d = new 狗(); d.show(); C:要有父類引用指向子類對象。 父 f = new 子(); 用代碼體現一下多態。 多態中的成員訪問特色: A:成員變量 編譯看左邊,運行看左邊。 B:構造方法 建立子類對象的時候,訪問父類的構造方法,對父類的數據進行初始化。 C:成員方法 編譯看左邊,運行看右邊。 D:靜態方法 編譯看左邊,運行看左邊。 (靜態和類相關,算不上重寫,因此,訪問仍是左邊的) 因爲成員方法存在方法重寫,因此它運行看右邊。 */
class Fu { public int num = 100; public void show() { System.out.println("show Fu"); } public static void function() { System.out.println("function Fu"); } } class Zi extends Fu { public int num = 1000; public int num2 = 200; public void show() { System.out.println("show Zi"); } public void method() { System.out.println("method zi"); } public static void function() { System.out.println("function Zi"); } } class DuoTaiDemo { public static void main(String[] args) { //要有父類引用指向子類對象。 //父 f = new 子(); Fu f = new Zi(); System.out.println(f.num); //找不到符號 //System.out.println(f.num2); f.show(); //找不到符號 //f.method(); f.function(); } }
/* 多態的弊端: 不能使用子類的特有功能。 我就想使用子類的特有功能?行不行? 行。 怎麼用呢? A:建立子類對象調用方法便可。(能夠,可是不少時候不合理。並且,太佔內存了) B:把父類的引用強制轉換爲子類的引用。(向下轉型) 對象間的轉型問題: 向上轉型: Fu f = new Zi(); 向下轉型: Zi z = (Zi)f; //要求該f必須是可以轉換爲Zi的。 */
多態的問題理解: class 孔子爹 { public int age = 40; public void teach() { System.out.println("講解JavaSE"); } } class 孔子 extends 孔子爹 { public int age = 20; public void teach() { System.out.println("講解論語"); } public void playGame() { System.out.println("英雄聯盟"); } } //Java培訓特別火,不少人來請孔子爹去講課,這一天孔子爹被請走了 //可是還有人來請,就剩孔子在家,價格還挺高。孔子一想,我是否是能夠考慮去呢? //而後就穿上爹的衣服,帶上爹的眼睛,粘上爹的鬍子。就開始裝爹 //向上轉型 孔子爹 k爹 = new 孔子(); //到人家那裏去了 System.out.println(k爹.age); //40 k爹.teach(); //講解論語 //k爹.playGame(); //這是兒子才能作的 //講完了,下班回家了 //脫下爹的裝備,換上本身的裝備 //向下轉型 孔子 k = (孔子) k爹; System.out.println(k.age); //20 k.teach(); //講解論語 k.playGame(); //英雄聯盟
靜態是隨着類的加載而加載的。
java
成員變量僅僅是該事物的外在特徵描述,而成員方法是該事物的功能描述。功能是內在特徵。面試
變量使用的是父類,方法是子類測試
/* ClassCastException:類型轉換異常 通常在多態的向下轉型中容易出現 */ class Animal { public void eat(){} } class Dog extends Animal { public void eat() {} public void lookDoor() { } } class Cat extends Animal { public void eat() { } public void playGame() { } } class DuoTaiDemo5 { public static void main(String[] args) { //內存中的是狗 Animal a = new Dog(); Dog d = (Dog)a; //內存中是貓 a = new Cat(); Cat c = (Cat)a; //內存中是貓 Dog dd = (Dog)a; //ClassCastException } }
/* 多態練習:貓狗案例 */ class Animal { public void eat(){ System.out.println("吃飯"); } } class Dog extends Animal { public void eat() { System.out.println("狗吃肉"); } public void lookDoor() { System.out.println("狗看門"); } } class Cat extends Animal { public void eat() { System.out.println("貓吃魚"); } public void playGame() { System.out.println("貓捉迷藏"); } } class DuoTaiTest { public static void main(String[] args) { //定義爲狗 Animal a = new Dog(); a.eat(); System.out.println("--------------"); //還原成狗 Dog d = (Dog)a; d.eat(); d.lookDoor(); System.out.println("--------------"); //變成貓 a = new Cat(); a.eat(); System.out.println("--------------"); //還原成貓 Cat c = (Cat)a; c.eat(); c.playGame(); System.out.println("--------------"); //演示錯誤的內容 //左大右小 //Dog dd = new Animal(); //Dog ddd = new Cat(); //ClassCastException //Dog dd = (Dog)a; } }
/* 看程序寫結果:先判斷有沒有問題,若是沒有,寫出結果 多態的成員訪問特色: 方法:編譯看左邊,運行看右邊。 繼承的時候: 子類中有和父類中同樣的方法,叫重寫。 子類中沒有父親中出現過的方法,方法就被繼承過來了。 */ class A { public void show() { show2(); } public void show2() { System.out.println("我"); } } class B extends A { /* public void show() { show2(); } */ public void show2() { System.out.println("愛"); } } class C extends B { public void show() { super.show(); } public void show2() { System.out.println("你"); } } public class DuoTaiTest4 { public static void main(String[] args) { A a = new B(); a.show(); B b = new C(); b.show(); } } /* 愛 你 */
/* 抽象類的概述: 動物不該該定義爲具體的東西,並且動物中的吃,睡等也不該該是具體的。 咱們把一個不是具體的功能稱爲抽象的功能,而一個類中若是有抽象的功能,該類必須是抽象類。 抽象類的特色: A:抽象類和抽象方法必須用abstract關鍵字修飾 B:抽象類中不必定有抽象方法,可是有抽象方法的類必須定義爲抽象類 C:抽象類不能實例化 由於它不是具體的。 抽象類有構造方法,可是不能實例化?構造方法的做用是什麼呢? 用於子類訪問父類數據的初始化 D:抽象的子類 a:若是不想重寫抽象方法,該子類是一個抽象類。 b:重寫全部的抽象方法,這個時候子類是一個具體的類。 抽象類的實例化實際上是靠具體的子類實現的。是多態的方式。 Animal a = new Cat(); */ //abstract class Animal //抽象類的聲明格式 abstract class Animal { //抽象方法 //public abstract void eat(){} //空方法體,這個會報錯。抽象方法不能有主體 public abstract void eat(); public Animal(){} } //子類是抽象類 abstract class Dog extends Animal {} //子類是具體類,重寫抽象方法 class Cat extends Animal { public void eat() { System.out.println("貓吃魚"); } } class AbstractDemo { public static void main(String[] args) { //建立對象 //Animal是抽象的; 沒法實例化 //Animal a = new Animal(); //經過多態的方式 Animal a = new Cat(); a.eat(); } }
/* 抽象類的成員特色: 成員變量:既能夠是變量,也能夠是常量。 構造方法:有。 用於子類訪問父類數據的初始化。 成員方法:既能夠是抽象的,也能夠是非抽象的。 抽象類的成員方法特性: A:抽象方法 強制要求子類作的事情。 B:非抽象方法 子類繼承的事情,提升代碼複用性。 */ abstract class Animal { public int num = 10; public final int num2 = 20; public Animal() {} public Animal(String name,int age){} public abstract void show(); public void method() { System.out.println("method"); } } class Dog extends Animal { public void show() { System.out.println("show Dog"); } } class AbstractDemo2 { public static void main(String[] args) { //建立對象 Animal a = new Dog(); a.num = 100; System.out.println(a.num); //a.num2 = 200; System.out.println(a.num2); System.out.println("--------------"); a.show(); a.method(); } }
因爲子類有特有的內容,因此咱們用子類來測試this
/* 一個類若是沒有抽象方法,可不能夠定義爲抽象類?若是能夠,有什麼意義? A:能夠。 B:不讓建立對象。 abstract不能和哪些關鍵字共存? private 衝突 final 衝突 static 無心義 */ abstract class Fu { public abstract void show(); //非法的修飾符組合: abstract和private;abstract自己就是要讓重寫,private是不讓重寫的,因此衝突 //private abstract void show(); //非法的修飾符組合 //final abstract void show(); //非法的修飾符組合 //static abstract void show(); public static void method() { System.out.println("method"); } } class Zi extends Fu { public void show() {} } class AbstractDemo3 { public static void main(String[] args) { Fu.method(); } }
/* 接口的特色: A:接口用關鍵字interface表示 interface 接口名 {} B:類實現接口用implements表示 class 類名 implements 接口名 {} C:接口不能實例化 那麼,接口如何實例化呢? 按照多態的方式來實例化。 D:接口的子類 a:能夠是抽象類。可是意義不大。 b:能夠是具體類。要重寫接口中的全部抽象方法。(推薦方案) 因而可知: A:具體類多態(幾乎沒有) B:抽象類多態(經常使用) C:接口多態(最經常使用) */ //定義動物培訓接口 interface AnimalTrain { public abstract void jump(); } //抽象類實現接口 abstract class Dog implements AnimalTrain { } //具體類實現接口 class Cat implements AnimalTrain { public void jump() { System.out.println("貓能夠跳高了"); } } class InterfaceDemo { public static void main(String[] args) { //AnimalTrain是抽象的; 沒法實例化 //AnimalTrain at = new AnimalTrain(); //at.jump(); AnimalTrain at = new Cat(); at.jump(); } }
/* 接口成員特色 成員變量;只能是常量,而且是靜態的。 默認修飾符:public static final 建議:本身手動給出。 構造方法:接口沒有構造方法。 成員方法:只能是抽象方法。 默認修飾符:public abstract 建議:本身手動給出。 全部的類都默認繼承自一個類:Object。 類 Object 是類層次結構的根類。每一個類都使用 Object 做爲超類。 */
/* 類與類: 繼承關係,只能單繼承,能夠多層繼承。 類與接口: 實現關係,能夠單實現,也能夠多實現。 而且還能夠在繼承一個類的同時實現多個接口。 接口與接口: 繼承關係,能夠單繼承,也能夠多繼承。 */ interface Father { public abstract void show(); } interface Mother { public abstract void show2(); } interface Sister extends Father,Mother { } //class Son implements Father,Mother //多實現 class Son extends Object implements Father,Mother { public void show() { System.out.println("show son"); } public void show2() { System.out.println("show2 son"); } } class InterfaceDemo3 { public static void main(String[] args) { //建立對象 Father f = new Son(); f.show(); //f.show2(); //報錯 Mother m = new Son(); //m.show(); //報錯 m.show2(); } }
抽象類和接口的區別: A:成員區別 抽象類: 成員變量:能夠變量,也能夠常量 構造方法:有 成員方法:能夠抽象,也能夠非抽象 接口: 成員變量:只能夠常量 成員方法:只能夠抽象 B:關係區別 類與類 繼承,單繼承 類與接口 實現,單實現,多實現 接口與接口 繼承,單繼承,多繼承 C:設計理念區別 抽象類 被繼承體現的是:」is a」的關係。抽象類中定義的是該繼承體系的共性功能。 接口 被實現體現的是:」like a」的關係。接口中定義的是該繼承體系的擴展功能。
/* 老師和學生案例,加入抽菸的額外功能 分析:從具體到抽象 老師:姓名,年齡,吃飯,睡覺 學生:姓名,年齡,吃飯,睡覺 因爲有共性功能,咱們提取出一個父類,人類。 人類: 姓名,年齡 吃飯(); 睡覺(){} 抽菸的額外功能不是人或者老師,或者學生一開始就應該具有的,因此,咱們把它定義爲接口 抽菸接口。 部分老師抽菸:實現抽菸接口 部分學生抽菸:實現抽菸接口 實現:從抽象到具體 使用:具體 */ //定義抽菸接口 interface Smoking { //抽菸的抽象方法 public abstract void smoke(); } //定義抽象人類 abstract class Person { //姓名 private String name; //年齡 private int age; public Person() {} public Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //吃飯(); public abstract void eat(); //睡覺(){} public void sleep() { System.out.println("睡覺覺了"); } } //具體老師類 class Teacher extends Person { public Teacher() {} public Teacher(String name,int age) { super(name,age); } public void eat() { System.out.println("吃大白菜"); } } //具體學生類 class Student extends Person { public Student() {} public Student(String name,int age) { super(name,age); } public void eat() { System.out.println("吃紅燒肉"); } } //抽菸的老師 class SmokingTeacher extends Teacher implements Smoking { public SmokingTeacher() {} public SmokingTeacher(String name,int age) { super(name,age); } public void smoke() { System.out.println("抽菸的老師"); } } //抽菸的學生 class SmokingStudent extends Student implements Smoking { public SmokingStudent() {} public SmokingStudent(String name,int age) { super(name,age); } public void smoke() { System.out.println("抽菸的學生"); } } class InterfaceTest2 { public static void main(String[] args) { //測試學生 SmokingStudent ss = new SmokingStudent(); ss.setName("林青霞"); ss.setAge(27); System.out.println(ss.getName()+"---"+ss.getAge()); ss.eat(); ss.sleep(); ss.smoke(); System.out.println("-------------------"); SmokingStudent ss2 = new SmokingStudent("劉意",30); System.out.println(ss2.getName()+"---"+ss2.getAge()); ss2.eat(); ss2.sleep(); ss2.smoke(); //測試老師留給本身練習 } }