Java面向對象03

面向對象·三級

代碼塊的概述和分類

* A:代碼塊概述
    * 在Java中,使用 { } 括起來的代碼被稱爲代碼塊。java

* B:代碼塊分類
    * 根據其位置和聲明的不一樣,能夠分爲局部代碼塊,構造代碼塊,靜態代碼塊,同步代碼塊(多線程講解)。ios


* C:常見代碼塊的應用
    * a:局部代碼塊 
        * 在方法中出現;限定變量生命週期,及早釋放,提升內存利用率程序員

    * b:構造代碼塊 (初始化塊)
        * 在類中方法外出現;多個構造方法方法中相同的代碼存放到一塊兒,每次調用構造都執行,而且在構造方法前執行面試

    * c:靜態代碼塊 
        *  在類中方法外出現,並加上static修飾;用於給類進行初始化,在加載類的時候就執行,而且只執行一次
        *  通常用於加載驅動
   *  優先於構造代碼塊多線程

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("我是靜態代碼塊");    //做用:用來給類進行初始化,通常用來加載驅動
    }                                            //靜態代碼塊是優先於主方法執行
}
View Code

 

 

代碼塊的面試題

看程序寫結果jvm

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(); } }
View Code

 

 


 

 

繼承案例演示

* A:繼承(extends)
    * 讓類與類之間產生關係,子父類關係 ide

* B:繼承案例演示:
    * 動物類,貓類,狗類
    * 定義兩個屬性 (顏色,腿的條數) 兩個功能 (吃飯,睡覺)函數

* C:案例演示
    * 使用繼承前學習

* D:案例演示
    * 使用繼承後測試

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都是子類 */
View Code

 

 

繼承的好處和弊端

* A:繼承的好處
    * a:提升了代碼的複用性
    * b:提升了代碼的維護性
    * c:讓類與類之間產生了關係,是多態的前提

* B:繼承的弊端
    * 類的耦合性加強了。
    * 開發的原則:高內聚,低耦合

    * 耦合:類與類的關係
    * 內聚:就是本身完成某件事情的能力

Java中類的繼承特色

* A:Java中類的繼承特色
    * a:Java只支持單繼承,不支持多繼承。(一個兒子只能有一個爹)
        * 有些語言是支持多繼承,格式:extends 類1,類2,...
    * b:Java支持多層繼承(繼承體系)

* B:案例演示
    * Java中類的繼承特色
        * 若是想用這個體系的全部功能最底層的類建立對象
        * 若是想看這個體系的共性功能,看最頂層的類 

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"); } }
View Code

 

 

繼承的注意事項

* A:繼承的注意事項
    * a:子類只能繼承父類全部非私有的成員(成員方法和成員變量)
    * b:子類不能繼承父類的構造方法,可是能夠經過super關鍵字去訪問父類構造方法。
    * c:不要爲了部分功能而去繼承
     * 項目經理   姓名 工號 工資 獎金
     * 程序員      姓名 工號 工資


* B:何時使用繼承
    * 繼承其實體現的是一種關係:"is a"。
        Person
            Student
            Teacher

        水果
            蘋果
            香蕉
            橘子
            
    採用假設法。
        若是有兩個類A,B。只有他們符合A是B的一種,或者B是A的一種,就能夠考慮使用繼承。

 

繼承中成員變量的關係

* A:案例演示
    * a:  不一樣名的變量
    * b:  同名的變量

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); } }
View Code

 

 

this和super的區別和應用

* A:this和super都表明什麼
    * this:    表明當前對象的引用,誰來調用我,我就表明誰
    * super: 表明當前對象父類的引用

* B:this和super的使用區別
    * a:調用成員變量
        * this.成員變量      調用本類的成員變量,可是在子類沒有該變量而父類中有時,也能夠調用父類的成員變量
        * super.成員變量   調用父類的成員變量

    * b:調用構造方法
        * this(...)       調用本類的構造方法
        * super(...)    調用父類的構造方法

    * c:調用成員方法
        * this.成員方法     調用本類的成員方法,可是在子類沒有該方法而父類中有時,也能夠調用父類的方法
        * super.成員方法  調用父類的成員方法

 

繼承中構造方法的關係

* A:案例演示
    * 子類中 全部的構造方法 默認都會訪問父類中空參數的構造方法

* B:爲何呢?
    * 由於子類會繼承父類中的數據,可能還會使用父類的數據。
    * 因此,子類初始化以前,必定要先完成父類數據的初始化
    
    * 其實:
        * 每個構造方法的第一條語句默認都是:super()
   * Object類最頂層的父類。

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 的構造方法"); } }
View Code

 

 

繼承中構造方法的注意事項

* A:案例演示
    * 父類沒有無參構造方法,子類怎麼辦?
     * super解決,  調用父類的有參構造
     * this解決,     調用本身的有參構造

* B:注意事項
    * super(…)或者this(….)   必須出如今構造方法的第一條語句上

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 有參構造"); } }
View Code

 

 

繼承中的面試題

看程序寫結果1

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(); } }
View Code

 

看程序寫結果2

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"); } }
View Code

 

 

繼承中成員方法關係

* A:案例演示
    * a:不一樣名的方法
    * b:同名的方法

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"); } }
View Code

 

 

方法重寫概述及其應用

* A:什麼是方法重寫
    * 重寫:子父類出現瞭如出一轍的方法(注意:返回值類型能夠是子父類,這個咱們學完面向對象講) 

* B:方法重寫的應用:
    * 當子類須要父類的功能,而功能主體子類有本身特有內容時,能夠重寫父類中的方法。這樣,即沿襲了父類的功能,又定義了子類特有的內容。

* C:案例演示
    * a:定義一個手機類

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(); } }
View Code

 

 

方法重寫的注意事項

* A:方法重寫注意事項
    * a:父類中私有方法不能被重寫
        * 由於父類私有方法子類根本就沒法繼承

    * b:子類重寫父類方法時,訪問權限不能更低
        * 最好就一致

    * c:父類靜態方法,子類也必須經過靜態方法進行重寫
        * 其實這個算不上方法重寫,可是現象確實如此,至於爲何算不上方法重寫,多態中我會講解(靜態只能覆蓋靜態)
        
    * 子類重寫父類方法的時候,最好聲明如出一轍。

* B:案例演示
    * 方法重寫注意事項

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"); } }
View Code

 

 

方法重寫的面試題

* A:方法重寫的面試題
    * Override和Overload的區別?Overload能改變返回值類型嗎?
    * overload能夠改變返回值類型,只看參數列表


    * 方法重寫:子類中出現了和父類中方法聲明如出一轍的方法。與返回值類型有關,返回值是一致(或者是子父類)的   
    * 方法重載:本類中出現的方法名同樣,參數列表不一樣的方法。與返回值類型無關。

    * 子類對象調用方法的時候:
        * 先找子類自己,再找父類。

 

使用繼承前的學生和老師案例

* A:案例演示
    * 使用繼承前的學生和老師案例
    * 屬性:姓名,年齡
    * 行爲:吃飯
    * 老師有特有的方法:講課
    * 學生有特有的方法:學習

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("老師講課"); } }
View Code

 

 

使用繼承後的學生和老師案例

* A:案例演示
    * 使用繼承後的學生和老師案例

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() + "講課"); } }
View Code

 

貓狗案例分析,實現及測試

* A:貓狗案例分析
* B:案例演示
    * 貓狗案例繼承版
    * 屬性:毛的顏色,腿的個數
    * 行爲:吃飯
    * 貓特有行爲:抓老鼠 catchMouse
    * 狗特有行爲:看家 lookHome

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("看家"); } }
View Code

 


 

 

final關鍵字修飾類,方法以及變量的特色

* A:final概述

* B:final修飾特色
    * 修飾類,     類不能被繼承
    * 修飾變量, 變量就變成了常量,只能被賦值一次
    * 修飾方法, 方法不能被重寫

* C:案例演示
    * final修飾特色

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); } }
View Code

 

 

final關鍵字修飾局部變量

* A:案例演示
    * 方法內部或者方法聲明上都演示一下(瞭解)

    * 基本類型, 值不能被改變
    * 引用類型, 地址值不能被改變, 對象中的屬性能夠改變

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; } }
View Code

 

 

final修飾變量的初始化時機

* A:final修飾變量的初始化時機
    * 顯式初始化 
    * 在對象構造完畢前便可

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); } }
View Code
相關文章
相關標籤/搜索