面向對象·三級
代碼塊的概述和分類
* A:代碼塊概述
* 在Java中,使用 { } 括起來的代碼被稱爲代碼塊。java
* B:代碼塊分類
* 根據其位置和聲明的不一樣,能夠分爲局部代碼塊,構造代碼塊,靜態代碼塊,同步代碼塊(多線程講解)。ios
* C:常見代碼塊的應用
* a:局部代碼塊
* 在方法中出現;限定變量生命週期,及早釋放,提升內存利用率程序員
* b:構造代碼塊 (初始化塊)
* 在類中方法外出現;多個構造方法方法中相同的代碼存放到一塊兒,每次調用構造都執行,而且在構造方法前執行面試
* c:靜態代碼塊
* 在類中方法外出現,並加上static修飾;用於給類進行初始化,在加載類的時候就執行,而且只執行一次。
* 通常用於加載驅動
* 優先於構造代碼塊多線程
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo1_Code { public static void main(String[] args) { { int x = 10; //限定變量的聲明週期 System.out.println(x); } Student s1 = new Student(); System.out.println("---------------"); Student s2 = new Student("張三",23); } static { System.out.println("我是在主方法類中的靜態代碼塊"); } } class Student { private String name; private int age; public Student(){ //study(); System.out.println("空參構造"); } //空參構造 public Student(String name,int age) {//有參構造 //study(); this.name = name; this.age = age; System.out.println("有參構造"); } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } { //構造代碼塊:每建立一次對象就會執行一次,優先於構造函數執行 //System.out.println("構造代碼塊"); study(); } public void study() { System.out.println("學生學習"); } static { //隨着類加載而加載,且只執行一次 System.out.println("我是靜態代碼塊"); //做用:用來給類進行初始化,通常用來加載驅動 } //靜態代碼塊是優先於主方法執行 }
代碼塊的面試題
看程序寫結果jvm
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Student { static { System.out.println("Student 靜態代碼塊"); } { System.out.println("Student 構造代碼塊"); } public Student() { System.out.println("Student 構造方法"); } } class Demo2_Student { static { System.out.println("Demo2_Student靜態代碼塊"); } public static void main(String[] args) { System.out.println("我是main方法"); Student s1 = new Student(); Student s2 = new Student(); } }
繼承案例演示
* A:繼承(extends)
* 讓類與類之間產生關係,子父類關係 ide
* B:繼承案例演示:
* 動物類,貓類,狗類
* 定義兩個屬性 (顏色,腿的條數) 兩個功能 (吃飯,睡覺)函數
* C:案例演示
* 使用繼承前學習
* D:案例演示
* 使用繼承後測試
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo1_Extends { public static void main(String[] args) { Cat c = new Cat(); c.color = "花"; c.leg = 4; c.eat(); c.sleep(); System.out.println(c.leg + "..." + c.color); } } /* * A:繼承(extends) * 讓類與類之間產生關係,子父類關係 * B:繼承案例演示: * 動物類,貓類,狗類 * 定義兩個屬性(顏色,腿的個數)兩個功能(吃飯,睡覺) * C:案例演示 * 使用繼承前 * D:案例演示 * 使用繼承後 */ class Animal { String color; //動物的顏色 int leg; //動物腿的個數 public void eat() { //吃飯的功能 System.out.println("吃飯"); } public void sleep() { //睡覺的功能 System.out.println("睡覺"); } } class Cat extends Animal { } class Dog extends Animal { } /* extends是繼承的意思 Animal是父類 Cat和Dog都是子類 */
繼承的好處和弊端
* A:繼承的好處
* a:提升了代碼的複用性
* b:提升了代碼的維護性
* c:讓類與類之間產生了關係,是多態的前提
* B:繼承的弊端
* 類的耦合性加強了。
* 開發的原則:高內聚,低耦合。
* 耦合:類與類的關係
* 內聚:就是本身完成某件事情的能力
Java中類的繼承特色
* A:Java中類的繼承特色
* a:Java只支持單繼承,不支持多繼承。(一個兒子只能有一個爹)
* 有些語言是支持多繼承,格式:extends 類1,類2,...
* b:Java支持多層繼承(繼承體系)
* B:案例演示
* Java中類的繼承特色
* 若是想用這個體系的全部功能用最底層的類建立對象
* 若是想看這個體系的共性功能,看最頂層的類
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo2_Extends { public static void main(String[] args) { DemoC d = new DemoC(); d.show(); } } /* * A:Java中類的繼承特色 * a:Java只支持單繼承,不支持多繼承。(一個兒子只能有一個爹) * 有些語言是支持多繼承,格式:extends 類1,類2,... * b:Java支持多層繼承(繼承體系) * B:案例演示 * Java中類的繼承特色 * 若是想用這個體系的全部功能用最底層的類建立對象 * 若是想看這個體系的共性功能,看最頂層的類 */ class DemoA { public void show() { System.out.println("DemoA"); } } class DemoB extends DemoA { public void method() { System.out.println("DemoB"); } } class DemoC extends DemoB { public void print() { System.out.println("DemoC"); } }
繼承的注意事項
* A:繼承的注意事項
* a:子類只能繼承父類全部非私有的成員(成員方法和成員變量)
* b:子類不能繼承父類的構造方法,可是能夠經過super關鍵字去訪問父類構造方法。
* c:不要爲了部分功能而去繼承
* 項目經理 姓名 工號 工資 獎金
* 程序員 姓名 工號 工資
* B:何時使用繼承
* 繼承其實體現的是一種關係:"is a"。
Person
Student
Teacher
水果
蘋果
香蕉
橘子
採用假設法。
若是有兩個類A,B。只有他們符合A是B的一種,或者B是A的一種,就能夠考慮使用繼承。
繼承中成員變量的關係
* A:案例演示
* a: 不一樣名的變量
* b: 同名的變量
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo4_Extends { public static void main(String[] args) { Son s = new Son(); s.print(); } } /* * A:案例演示 * a:不一樣名的變量 * b:同名的變量 子父類出現同名的變量只是在講課中舉例子有,在開發中是不會出現這種狀況的 子類繼承父類就是爲了使用父類的成員,那麼若是定義了同名的成員變量沒有意義了 */ class Father { int num1 = 10; int num2 = 30; } class Son extends Father { int num2 = 20; public void print() { System.out.println(this.num1); //this既能夠調用本類的,也能夠調用父類的(本類沒有的狀況下) System.out.println(this.num2); //就近原則,子類有就不用父類的了 System.out.println(super.num2); } }
this和super的區別和應用
* A:this和super都表明什麼
* this: 表明當前對象的引用,誰來調用我,我就表明誰
* super: 表明當前對象父類的引用
* B:this和super的使用區別
* a:調用成員變量
* this.成員變量 調用本類的成員變量,可是在子類沒有該變量而父類中有時,也能夠調用父類的成員變量
* super.成員變量 調用父類的成員變量
* b:調用構造方法
* this(...) 調用本類的構造方法
* super(...) 調用父類的構造方法
* c:調用成員方法
* this.成員方法 調用本類的成員方法,可是在子類沒有該方法而父類中有時,也能夠調用父類的方法
* super.成員方法 調用父類的成員方法
繼承中構造方法的關係
* A:案例演示
* 子類中 全部的構造方法 默認都會訪問父類中空參數的構造方法
* B:爲何呢?
* 由於子類會繼承父類中的數據,可能還會使用父類的數據。
* 因此,子類初始化以前,必定要先完成父類數據的初始化。
* 其實:
* 每個構造方法的第一條語句默認都是:super()
* Object類最頂層的父類。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo5_Extends { public static void main(String[] args) { Son s = new Son(); } } /* * A:案例演示 * 子類中全部的構造方法默認都會訪問父類中空參數的構造方法 * B:爲何呢? * 由於子類會繼承父類中的數據,可能還會使用父類的數據。 * 因此,子類初始化以前,必定要先完成父類數據的初始化。 * 其實: * 每個構造方法的第一條語句默認都是:super() Object類最頂層的父類。 */ class Father extends Object { public Father() { super(); System.out.println("Father 的構造方法"); } } class Son extends Father { public Son() { super(); //這是一條語句,若是不寫,系統會默認加上,用來訪問父類中的空參構造 System.out.println("Son 的構造方法"); } }
繼承中構造方法的注意事項
* A:案例演示
* 父類沒有無參構造方法,子類怎麼辦?
* super解決, 調用父類的有參構造
* this解決, 調用本身的有參構造
* B:注意事項
* super(…)或者this(….) 必須出如今構造方法的第一條語句上
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo6_Extends { public static void main(String[] args) { Son s1 = new Son(); System.out.println(s1.getName() + "..." + s1.getAge()); System.out.println("--------------------"); Son s2 = new Son("張三",23); System.out.println(s2.getName() + "..." + s2.getAge()); } } /* * A:案例演示 * 父類沒有無參構造方法,子類怎麼辦? * super解決 * this解決 * B:注意事項 * super(…)或者this(….)必須出如今構造方法的第一條語句上 */ class Father { private String name; //姓名 private int age; //年齡 public Father() { //空參構造 System.out.println("Father 空參構造"); } public Father(String name,int age) { //有參構造 this.name = name; this.age = age; System.out.println("Father 有參構造"); } public void setName(String name) { //設置姓名 this.name = name; } public String getName() { //獲取姓名 return name; } public void setAge(int age) { //設置年齡 this.age = age; } public int getAge() { //獲取年齡 return age; } } class Son extends Father { public Son() { //空參構造 this("王五",25); //本類中的構造方法 //super("李四",24); //調用父類中的構造方法 System.out.println("Son 空參構造"); } public Son(String name,int age) { //有參構造 super(name,age); System.out.println("Son 有參構造"); } }
繼承中的面試題
看程序寫結果1
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Fu{ public int num = 10; public Fu(){ System.out.println("fu"); } } class Zi extends Fu{ public int num = 20; public Zi(){ //super(); System.out.println("zi"); } public void show(){ int num = 30; System.out.println(num); System.out.println(this.num); System.out.println(super.num); } } class Test1_Extends { public static void main(String[] args) { Zi z = new Zi(); z.show(); } }
看程序寫結果2
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Test2_Extends { public static void main(String[] args) { Zi z = new Zi(); } /* 1,jvm調用了main方法,main進棧 2,遇到Zi z = new Zi();會先將Fu.class和Zi.class分別加載進內存,再建立對象,當Fu.class加載進內存 父類的靜態代碼塊會隨着Fu.class一塊兒加載,當Zi.class加載進內存,子類的靜態代碼塊會隨着Zi.class一塊兒加載 第一個輸出,靜態代碼塊Fu,第二個輸出靜態代碼塊Zi 3,走Zi類的構造方法,由於java中是分層初始化的,先初始化父類,再初始化子類,因此先走的父類構造,可是在執行 父類構造時,發現父類有構造代碼塊,構造代碼塊是優先於構造方法執行的因此 第三個輸出構造代碼塊Fu,第四個輸出構造方法Fu 4,Fu類初始化結束,子類初始化,第五個輸出的是構造代碼塊Zi,構造方法Zi */ } class Fu { static { System.out.println("靜態代碼塊Fu"); } { System.out.println("構造代碼塊Fu"); } public Fu() { System.out.println("構造方法Fu"); } } class Zi extends Fu { static { System.out.println("靜態代碼塊Zi"); } { System.out.println("構造代碼塊Zi"); } public Zi() { System.out.println("構造方法Zi"); } }
繼承中成員方法關係
* A:案例演示
* a:不一樣名的方法
* b:同名的方法
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo7_Extends { public static void main(String[] args) { Son s = new Son(); s.print(); s.method(); } } /* * a:不一樣名的方法 * b:同名的方法 */ class Father { public void print() { System.out.println("Fu print"); } } class Son extends Father { public void method() { System.out.println("Zi Method"); } public void print() { super.print(); //super能夠調用父類的成員方法 System.out.println("Zi print"); } }
方法重寫概述及其應用
* A:什麼是方法重寫
* 重寫:子父類出現瞭如出一轍的方法(注意:返回值類型能夠是子父類,這個咱們學完面向對象講)
* B:方法重寫的應用:
* 當子類須要父類的功能,而功能主體子類有本身特有內容時,能夠重寫父類中的方法。這樣,即沿襲了父類的功能,又定義了子類特有的內容。
* C:案例演示
* a:定義一個手機類
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo7_Phone { public static void main(String[] args) { Ios8 i = new Ios8(); i.siri(); i.call(); } } /* B:方法重寫的應用: * 當子類須要父類的功能,而功能主體子類有本身特有內容時,能夠重寫父類中的方法。這樣,即沿襲了父類的功能,又定義了子類特有的內容。 ios7系統 siri speak English ios8系統 siri 說中文 */ class Ios7 { public void call() { System.out.println("打電話"); } public void siri() { System.out.println("speak English"); } } class Ios8 extends Ios7 { public void siri() { System.out.println("說中文"); super.siri(); } }
方法重寫的注意事項
* A:方法重寫注意事項
* a:父類中私有方法不能被重寫
* 由於父類私有方法子類根本就沒法繼承
* b:子類重寫父類方法時,訪問權限不能更低
* 最好就一致
* c:父類靜態方法,子類也必須經過靜態方法進行重寫
* 其實這個算不上方法重寫,可是現象確實如此,至於爲何算不上方法重寫,多態中我會講解(靜態只能覆蓋靜態)
* 子類重寫父類方法的時候,最好聲明如出一轍。
* B:案例演示
* 方法重寫注意事項
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo8_雙槳 { public static void main(String[] args) { DayOne d = new DayOne(); d.泡妞(); d.print(); } } /* * a:父類中私有方法不能被重寫 * 由於父類私有方法子類根本就沒法繼承 * b:子類重寫父類方法時,訪問權限不能更低 * 最好就一致 * c:父類靜態方法,子類也必須經過靜態方法進行重寫 * 其實這個算不上方法重寫,可是現象確實如此,至於爲何算不上方法重寫,多態中我會講解(靜態只能覆蓋靜態) * 子類重寫父類方法的時候,最好聲明如出一轍。 */ class 雙槳 { public void sing() { System.out.println("唱紅歌"); } public void 泡妞() { System.out.println("唱紅歌搞定林夕合鳥女士"); } public static void print() { System.out.println("Fu print"); } } class DayOne extends 雙槳 { public void 泡妞() { System.out.println("霸王硬上弓"); } public static void print() { //靜態只能覆蓋靜態,其實不算重寫,多態時候詳細講解 System.out.println("Zi print"); } }
方法重寫的面試題
* A:方法重寫的面試題
* Override和Overload的區別?Overload能改變返回值類型嗎?
* overload能夠改變返回值類型,只看參數列表
* 方法重寫:子類中出現了和父類中方法聲明如出一轍的方法。與返回值類型有關,返回值是一致(或者是子父類)的
* 方法重載:本類中出現的方法名同樣,參數列表不一樣的方法。與返回值類型無關。
* 子類對象調用方法的時候:
* 先找子類自己,再找父類。
使用繼承前的學生和老師案例
* A:案例演示
* 使用繼承前的學生和老師案例
* 屬性:姓名,年齡
* 行爲:吃飯
* 老師有特有的方法:講課
* 學生有特有的方法:學習
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Test3_Person { public static void main(String[] args) { System.out.println("Hello World!"); } } /* * 使用繼承前的學生和老師案例 * 屬性:姓名,年齡 * 行爲:吃飯 * 老師有特有的方法:講課 * 學生有特有的方法:學習 */ class Student { private String name; //姓名 private int age; //年齡 public Student() {} //空參構造 public Student(String name,int age) { //有參構造 this.name = name; this.age = age; } public void setName(String name) { //設置姓名 this.name = name; } public String getName() { //獲取姓名 return name; } public void setAge(int age) { //設置年齡 this.age = age; } public int getAge() { //獲取年齡 return age; } public void eat() { //吃飯 System.out.println("學生吃飯"); } public void study() { //學習 System.out.println("學生學習"); } } class Teacher { private String name; //姓名 private int age; //年齡 public Teacher() {} //空參構造 public Teacher(String name,int age) { //有參構造 this.name = name; this.age = age; } public void setName(String name) { //設置姓名 this.name = name; } public String getName() { //獲取姓名 return name; } public void setAge(int age) { //設置年齡 this.age = age; } public int getAge() { //獲取年齡 return age; } public void eat() { //吃飯 System.out.println("老師吃飯"); } public void teach() { //學習 System.out.println("老師講課"); } }
使用繼承後的學生和老師案例
* A:案例演示
* 使用繼承後的學生和老師案例
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Test4_Person { public static void main(String[] args) { Student s1 = new Student(); s1.setName("張三"); s1.setAge(23); System.out.println(s1.getName() + "..." + s1.getAge()); s1.eat(); s1.study(); System.out.println("------------------"); Student s2 = new Student("李四",24); System.out.println(s2.getName() + "..." + s2.getAge()); s2.eat(); s2.study(); } } /* * 使用繼承後的學生和老師案例 */ class Person { private String name; //姓名 private int age; //年齡 public Person() {} //空參構造 public Person(String name,int age) { //有參構造 this.name = name; this.age = age; } public void setName(String name) { //設置姓名 this.name = name; } public String getName() { //獲取姓名 return name; } public void setAge(int age) { //設置年齡 this.age = age; } public int getAge() { //獲取年齡 return age; } public void eat() { //吃飯 System.out.println(name + "吃飯"); } } class Student extends Person { public Student() {} //空參構造 public Student(String name,int age) { super(name,age); } public void study() { System.out.println(this.getName() + "學習"); } } class Teacher extends Person { public Teacher() {} //空參構造 public Teacher(String name,int age) { super(name,age); } public void teach() { System.out.println(this.getName() + "講課"); } }
貓狗案例分析,實現及測試
* A:貓狗案例分析
* B:案例演示
* 貓狗案例繼承版
* 屬性:毛的顏色,腿的個數
* 行爲:吃飯
* 貓特有行爲:抓老鼠 catchMouse
* 狗特有行爲:看家 lookHome
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Test5_Animal { public static void main(String[] args) { Cat c1 = new Cat("花",4); System.out.println(c1.getColor() + "..." + c1.getLeg()); c1.eat(); c1.catchMouse(); Dog d1 = new Dog("黑",2); System.out.println(d1.getColor() + "..." + d1.getLeg()); d1.eat(); d1.lookHome(); } } /* * A:貓狗案例分析 * B:案例演示 * 貓狗案例繼承版 * 屬性:毛的顏色,腿的個數 * 行爲:吃飯 * 貓特有行爲:抓老鼠catchMouse * 狗特有行爲:看家lookHome */ class Animal { private String color; //毛的顏色 private int leg; //腿的個數 public Animal(){} public Animal(String color,int leg) { this.color = color; this.leg = leg; } public void setColor(String color) { //設置顏色 this.color = color; } public String getColor() { //獲取顏色 return color; } public void setLeg(int leg) { //設置腿的個數 this.leg = leg; } public int getLeg() { //獲取腿的個數 return leg; } public void eat() { //吃飯 System.out.println("吃飯"); } } class Cat extends Animal { public Cat() {} //空參構造 public Cat(String color,int leg) { //有參構造 super(color,leg); } public void eat() { //吃魚 System.out.println("貓吃魚"); } public void catchMouse() { //抓老鼠 System.out.println("抓老鼠"); } } class Dog extends Animal { public Dog() {} //空參構造 public Dog(String color,int leg) { //有參構造 super(color,leg); } public void eat() { //吃肉 System.out.println("狗吃肉"); } public void lookHome() { //看家 System.out.println("看家"); } }
final關鍵字修飾類,方法以及變量的特色
* A:final概述
* B:final修飾特色
* 修飾類, 類不能被繼承
* 修飾變量, 變量就變成了常量,只能被賦值一次
* 修飾方法, 方法不能被重寫
* C:案例演示
* final修飾特色
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo1_Final { public static void main(String[] args) { Son s = new Son(); s.print(); } } /* * A:final概述 final是最終的 * B:final修飾特色 * 修飾類,類不能被繼承 * 修飾變量,變量就變成了常量,只能被賦值一次 * 修飾方法,方法不能被重寫 * C:案例演示 * final修飾特色 */ /*final class Father { public void print() { System.out.println("訪問底層數據資源"); } }*/ class Son /*extends Father*/ { final int NUM = 10; //常量命名規範,若是是一個單詞,全部字母大寫,若是是多個單詞,每一個單詞都大寫,中間用下劃線隔開 public static final double PI = 3.14; //final修飾變量叫作常量,通常會與public static共用 public void print() { //NUM = 20; System.out.println(NUM); } }
final關鍵字修飾局部變量
* A:案例演示
* 方法內部或者方法聲明上都演示一下(瞭解)
* 基本類型, 值不能被改變
* 引用類型, 地址值不能被改變, 對象中的屬性能夠改變
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo2_Final { public static void main(String[] args) { final int num = 10; //num = 20; System.out.println(num); final Person p = new Person("張三",23); //p = new Person("李四",24); p.setName("李四"); p.setAge(24); System.out.println(p.getName() + "..." + p.getAge()); method(10); method(20); } public static void method(final int x) { System.out.println(x); } } /* * A:案例演示 * 方法內部或者方法聲明上都演示一下(瞭解) * 基本類型,是值不能被改變 * 引用類型,是地址值不能被改變,對象中的屬性能夠改變 */ class Person { private String name; //姓名 private int age; //年齡 public Person(){} //空參構造 public Person(String name,int age) { this.name = name; this.age = age; } public void setName(String name) { //設置姓名 this.name = name; } public String getName() { //獲取姓名 return name; } public void setAge(int age) { //設置年齡 this.age = age; } public int getAge() { //獲取年齡 return age; } }
final修飾變量的初始化時機
* A:final修飾變量的初始化時機
* 顯式初始化
* 在對象構造完畢前便可
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
class Demo3_Final { public static void main(String[] args) { Demo d = new Demo(); d.print(); } } /* * A:final修飾變量的初始化時機 * 顯示初始化 * 在對象構造完畢前便可 */ class Demo { final int num; //成員變量的默認初始化值是無效值 public Demo() { num = 10; } public void print() { System.out.println(num); } }