面向对象--多态,接口
一、final關(guān)鍵字
1、final,關(guān)鍵字,含義:不可更改的
2、final可以修飾的內(nèi)容:類(lèi),成員變量,成員方法
3、修飾類(lèi):類(lèi)不能被繼承
4、修飾成員變量:變量變?yōu)槌A?/p>
5、修飾成員方法:方法不能被重寫(xiě)
6、常量定義的格式:public static final double PI = 3.141592653589793;
(1)public是什么情況下都能訪問(wèn)
(2)static在不創(chuàng)建對(duì)象的時(shí)候也能方便使用
(3)final常量不能修改
代碼示例
public class Demo01_Final {public static void main(String[] args) {} }//extends 增加、擴(kuò)展/*final class A {}*/class A {}class B extends A { //final int num = 10;public final void show() {//System.out.println(num);//num = 11; } }class C extends B {public static final double PI = 3.141592653589793;/*@Override public void show() {super.show(); }*/ }二、多態(tài)
(一)多態(tài)的概述
1、多態(tài):事物的多種狀態(tài)
2、對(duì)象的多態(tài)性:同一個(gè)對(duì)象,可能具有不同的名稱(chēng),可以有不同類(lèi)型的引用指向他。本質(zhì):同一個(gè)物對(duì)象,有不同的名稱(chēng)和描述。
3、類(lèi)的多態(tài)性:同一個(gè)類(lèi)型,可能有不同子類(lèi)的實(shí)現(xiàn)。同一個(gè)類(lèi)型的引用,可能會(huì)指向不同子類(lèi)的對(duì)象。本質(zhì):同一個(gè)名字和描述,可能在不同的場(chǎng)景下有不同的實(shí)現(xiàn)。
4、多態(tài)的前提:
(1)要有繼承關(guān)系
(2)有方法的重寫(xiě)
(3)父類(lèi)引用指向子類(lèi)對(duì)象
(二)多態(tài)中成員變量的訪問(wèn)特點(diǎn)
1、編譯看左邊,運(yùn)行看左邊
2、【編譯看左邊】:左邊指的是【=】的左邊,如果左側(cè)父類(lèi)中沒(méi)有定義相關(guān)的變量,就會(huì)編譯不通過(guò)
3、【運(yùn)行看左邊】:左邊指的是【=】的左邊,如果左側(cè)父類(lèi)中有對(duì)應(yīng)的成員變量,就會(huì)執(zhí)行父類(lèi)中的成員變量
代碼示例
public class Demo02_Fields {public static void main(String[] args) {//父類(lèi)引用指向子類(lèi)對(duì)象//成員變量是從一個(gè)類(lèi)的角度去描述一個(gè)對(duì)象Animal a = new Cat();//Cat a = new Cat();//編譯看左邊,運(yùn)行看左邊System.out.println(a.color);System.out.println(a.age); } }public class Animal { String color = "動(dòng)物類(lèi)的color屬性"; int age = 30; }public class Cat extends Animal { String color = "橘色的貓"; int age = 3; }(三)多態(tài)種成員方法的訪問(wèn)特點(diǎn)
1、編譯看左邊,運(yùn)行看右邊
2、【編譯看左邊】:左邊指的是【=】的左邊,如果左側(cè)父類(lèi)中沒(méi)有定義相關(guān)的方法,就會(huì)編譯不通過(guò)
3、【運(yùn)行看右邊】:右邊指的是【=】的右邊,如果右側(cè)對(duì)象所屬類(lèi)型中有相應(yīng)的成員方法,就會(huì)執(zhí)行對(duì)象所屬類(lèi)型的方法
代碼示例
public class Demo02_Fields {public static void main(String[] args) {Animal a = new Cat();a.call(); }/*** 多態(tài)種成員變量的訪問(wèn)特點(diǎn)*/ public static void test1() {//父類(lèi)引用指向子類(lèi)對(duì)象//成員變量是從一個(gè)類(lèi)的角度去描述一個(gè)對(duì)象Animal a = new Cat();//Cat a = new Cat();//編譯看左邊,運(yùn)行看左邊System.out.println(a.color);System.out.println(a.age); }}
package com.offcn.demos;
public class Animal {
String color = “動(dòng)物類(lèi)的color屬性”;
int age = 30;
(四)多態(tài)中靜態(tài)方法的訪問(wèn)特點(diǎn)
1、編譯看左邊,運(yùn)行看左邊
2、靜態(tài)的最終解釋:
(1)靜態(tài)變量:存儲(chǔ)在類(lèi)的字節(jié)碼文件中,被所有對(duì)象共享,不隨著對(duì)象的變化而變化,所有的對(duì)象都具有相同的靜態(tài)變量,所以稱(chēng)之為靜態(tài)變量
(2)靜態(tài)方法:只會(huì)根據(jù)引用所屬的父類(lèi)類(lèi)型,來(lái)決定要運(yùn)行的內(nèi)容,和對(duì)象沒(méi)有任何關(guān)系,不會(huì)隨著對(duì)象的變化而變化,所以稱(chēng)之為靜態(tài)方法
(3)多態(tài)討論的是對(duì)象的情況,靜態(tài)與對(duì)象無(wú)關(guān),所以靜態(tài)的成員只根據(jù)類(lèi)來(lái)討論,不用考慮多態(tài)性,靜態(tài)也不具備多態(tài)性
代碼示例
public class Demo02_Fields {public static void main(String[] args) {Animal a = new Cat();a.test(); }/*** 多態(tài)種成員方法的訪問(wèn)特點(diǎn)*/ public static void test2() {Animal a = new Cat();a.call(); }/*** 多態(tài)種成員變量的訪問(wèn)特點(diǎn)*/ public static void test1() {//父類(lèi)引用指向子類(lèi)對(duì)象//成員變量是從一個(gè)類(lèi)的角度去描述一個(gè)對(duì)象Animal a = new Cat();//Cat a = new Cat();//編譯看左邊,運(yùn)行看左邊System.out.println(a.color);System.out.println(a.age); } }public class Animal { String color = "動(dòng)物類(lèi)的color屬性"; int age = 30;public void call() {System.out.println("動(dòng)物叫"); }public static void test() {System.out.println("Animal類(lèi)中的test方法執(zhí)行了"); } }public class Cat extends Animal { String color = "橘色的貓"; int age = 3;@Override public void call() {System.out.println("喵喵喵"); }public static void test() {System.out.println("Cat類(lèi)中的test方法執(zhí)行了"); } }(五)鋼鐵俠案例
1、向下轉(zhuǎn)型:
(1)在多態(tài)中是父類(lèi)引用指向子類(lèi)對(duì)象,討論的范疇是基于父類(lèi)范疇的
(2)如果子類(lèi)對(duì)象想要執(zhí)行自己所屬類(lèi)型特有的方法,就要從父類(lèi)引用指向子類(lèi)對(duì)象變?yōu)楸绢?lèi)引用指向本類(lèi)對(duì)象
(3)格式:(目標(biāo)類(lèi)型)要轉(zhuǎn)換的對(duì)象:IronMan im = (IronMan)m;
(4)本質(zhì):恢復(fù)了子對(duì)對(duì)象原本具有的訪問(wèn)范圍
2、向上轉(zhuǎn)型:原本使用子類(lèi)引用指向子類(lèi)對(duì)象,變成了父類(lèi)引用指向子類(lèi)對(duì)象。本質(zhì):縮小了訪問(wèn)范圍,減少了訪問(wèn)權(quán)限
代碼示例
public class Demo03_IronMan {public static void main(String[] args) {/*Man m = new IronMan();System.out.println(m.name);m.dealBusiness();//向下轉(zhuǎn)型IronMan im = (IronMan)m;im.fly();*///向上轉(zhuǎn)型IronMan im1 = new IronMan();Man m = im1; }public static void test() {/*double a = 3.3;int num = (int)a;*/int num = 10;double a = num; } }/*** 人類(lèi)* * @author Zihuatanejo * */ class Man { String name = "托尼史塔克";public void dealBusiness() {System.out.println("談生意"); } }/*** 鋼鐵俠* * @author Zihuatanejo**/ class IronMan extends Man { String name = "鋼鐵俠";@Override public void dealBusiness() {System.out.println("談幾個(gè)億的大生意"); }public void fly() {System.out.println("飛"); } }(六)多態(tài)在內(nèi)存中的原理
1、在訪問(wèn)成員變量時(shí),由于引用是父類(lèi)類(lèi)型,身份和權(quán)限就與super類(lèi)似,因此只能訪問(wèn)父類(lèi)部分的數(shù)據(jù)
2、在訪問(wèn)成員方法時(shí),進(jìn)行動(dòng)態(tài)綁定,判斷當(dāng)前對(duì)象到底屬于哪個(gè)類(lèi)型,就回去具體綁定對(duì)象所屬類(lèi)型中那個(gè)對(duì)應(yīng)的方法
3、動(dòng)態(tài)綁定:在程序運(yùn)行的過(guò)程中,會(huì)具體的判斷當(dāng)前對(duì)象到底是哪個(gè)類(lèi)型的對(duì)象,對(duì)象屬于哪個(gè)類(lèi)型,就執(zhí)行對(duì)象所屬類(lèi)型的方法
4、注意:動(dòng)態(tài)綁定只發(fā)生在運(yùn)行期,所以在編譯期首先要語(yǔ)法通過(guò)。動(dòng)態(tài)綁定只針對(duì)非靜態(tài)方法。
5、圖示:
代碼示例
public class Demo03_IronMan {public static void main(String[] args) {/*Man m = new IronMan();System.out.println(m.name);m.dealBusiness();//向下轉(zhuǎn)型IronMan im = (IronMan)m;im.fly();*///向上轉(zhuǎn)型IronMan im1 = new IronMan();Man m = im1; }public static void test() {/*double a = 3.3;int num = (int)a;*/int num = 10;double a = num; } }/*** 人類(lèi)* * @author Zihuatanejo**/ class Man { String name = "托尼史塔克";public void dealBusiness() {System.out.println("談生意"); } }/*** 鋼鐵俠* * @author Zihuatanejo**/ class IronMan extends Man { String name = "鋼鐵俠";@Override public void dealBusiness() {System.out.println("談幾個(gè)億的大生意"); }public void fly() {System.out.println("飛"); } }(七)多態(tài)的好處
1、提高了代碼的可擴(kuò)展性
2、在方法的參數(shù)列表中定義父類(lèi)的引用,將來(lái)傳入子類(lèi)的對(duì)象都可以使用
3、在實(shí)際開(kāi)發(fā)中,對(duì)象的來(lái)源非常廣泛,例如:自己new的,調(diào)用方法返回的,文件中讀取的,框架底層利用反射機(jī)制自動(dòng)創(chuàng)建的,從網(wǎng)絡(luò)中傳輸?shù)牡鹊?#xff0c;如果使用之前本類(lèi)引用指向本類(lèi)對(duì)象,接受對(duì)應(yīng)的對(duì)象難度較大,可以結(jié)合多態(tài),保證接收的遍歷。
代碼示例
/*** 榨汁機(jī)案例* * @author Zihuatanejo**/ public class Demo04_Juicing {public static void main(String[] args) {JuiceMachine jm = new JuiceMachine();Apple a = new Apple();Pear p = new Pear();Melon m = new Melon();jm.makeJuice(a);jm.makeJuice(p);jm.makeJuice(m);jm.makeJuice(new Mango()); } }class JuiceMachine {public void makeJuice(Fruit f) {//Fruit f = new Apple();f.flow(); }/*public void makeJuice(Apple a) {a.flow(); }public void makeJuice(Pear p) {p.flow(); }public void makeJuice(Melon m) {m.flow(); }*/}class Fruit {public void flow() {System.out.println("流出水果汁"); } }class Apple extends Fruit {public void flow() {System.out.println("流出蘋(píng)果汁"); } }class Pear extends Fruit {public void flow() {System.out.println("流出冰糖雪梨汁"); } }class Melon extends Fruit {public void flow() {System.out.println("流出西瓜汁"); } }class Mango extends Fruit {@Override public void flow() {System.out.println("流出芒果汁"); } }(八)instanceof關(guān)鍵字
1、instanceof,關(guān)鍵字,是一個(gè)運(yùn)算符,結(jié)果是一個(gè)布爾類(lèi)型的結(jié)果
2、格式:A instanceof B
3、作用:A是一個(gè)對(duì)象,B是一個(gè)類(lèi)型。用于判斷A對(duì)象是否和B類(lèi)型有關(guān),如果A對(duì)象和B類(lèi)型有關(guān)就返回true,否則返回false
4、所謂有關(guān):A對(duì)象是B類(lèi)型的對(duì)象,或者是B類(lèi)型子類(lèi)的對(duì)象
代碼示例
/*** 畫(huà)筆案例* * @author Zihuatanejo**/ public class Demo05_Pen {public static void main(String[] args) {//Pen b = new Brush();//Pen b = new DrawPen();Pen b = new EyePen();Painter p = new Painter();p.drawPicture(b); } }/** * 筆類(lèi)* * @author Zihuatanejo**/ class Pen {public void write() {System.out.println("筆畫(huà)出印記"); }}/*** * 畫(huà)筆類(lèi)* * @author Zihuatanejo**/ class Pencile extends Pen {public void drawing() {System.out.println("畫(huà)畫(huà)"); }}
/*** 毛筆類(lèi)* * @author Zihuatanejo * */ class DrawPen extends Pencile { @Override public void drawing() {System.out.println("畫(huà)中國(guó)畫(huà)"); } }/*** 排筆* * @author Zihuatanejo**/ class Brush extends Pencile {@Override public void drawing() {System.out.println("畫(huà)油畫(huà)"); } }/*** 眼線筆* * @author Zihuatanejo* */ class EyePen extends Pen {}/** * 畫(huà)家類(lèi) * * @author Zihuatanejo**/ class Painter {public void drawPicture(Pen p) {//Pen p = new Brush();//1.判斷當(dāng)前對(duì)象是否為畫(huà)筆類(lèi)型的對(duì)象if(p instanceof Pencile) {//2.如果是畫(huà)筆類(lèi)對(duì)象,就向下轉(zhuǎn)型為畫(huà)筆,調(diào)用畫(huà)畫(huà)的方法Pencile pe = (Pencile)p;//Pencile pe = new Brush();pe.drawing();} else {p.write();}} }三、抽象
(一)抽象方法
1、抽象:抽取相似的、相同的代碼部分
2、抽象方法:只有方法聲明沒(méi)有方法實(shí)現(xiàn)的方法,就是抽象方法,額外的在方法的聲明上加上abstract關(guān)鍵字,來(lái)表示是一個(gè)抽象方法
3、定義格式:抽象方法只有方法聲明沒(méi)有方法實(shí)現(xiàn),連大括號(hào)都沒(méi)有,直接在參數(shù)列表之后加上分號(hào),在方法的聲明上額外添加abstract關(guān)鍵字即可
(二)抽象類(lèi)
1、可以定義抽象方法的類(lèi)就是抽象類(lèi)(普通的類(lèi)不能定義抽象方法)
2、格式:
abstract class 類(lèi)名 {}
代碼示例
public class Demo01_Abstract {public static void main(String[] args) {/*Animal a = new Dog();a.call();*/Person p = new Student();p.work(); } }abstract class Person { public abstract void work(); }class Student extends Person {@Override public void work() {System.out.println("學(xué)生學(xué)習(xí)"); }}class Teacher extends Person {@Override public void work() {System.out.println("老師工作"); } }/*** 動(dòng)物類(lèi)* * @author Zihuatanejo* */ abstract class Animal {public abstract void call();//抽象方法 }class Cat extends Animal {@Override public void call() {System.out.println("喵喵喵"); }}class Dog extends Animal {@Override public void call() {System.out.println("汪汪汪"); }}(三)抽象類(lèi)的特點(diǎn)
1、抽象類(lèi)和抽象方法都必須使用abstract關(guān)鍵字來(lái)修飾
(1)抽象類(lèi):abstract class 類(lèi)名 {}
(2)抽象方法:public abstract void 方法名(參數(shù)列表);
2、抽象類(lèi)和抽象方法的關(guān)系:
(1)抽象方法所在類(lèi)必須是抽象類(lèi)
(2)抽象類(lèi)中未必都是抽象方法
3、抽象類(lèi)不能實(shí)例化(抽象類(lèi)不能創(chuàng)建對(duì)象)
4、抽象類(lèi)的前途:通過(guò)范圍更小更加具體的子類(lèi)來(lái)實(shí)現(xiàn)抽象類(lèi)
(1)雖然抽象類(lèi)不能創(chuàng)建對(duì)象,但是抽象類(lèi)可以被繼承,如果范圍降低到一定程度,可以將方法具體的實(shí)現(xiàn)加上,那么就在這個(gè)子類(lèi)中,重寫(xiě)(實(shí)現(xiàn))這個(gè)抽象方法,讓其變?yōu)榫唧w的方法,此時(shí),這個(gè)方法所在的類(lèi)就變成了一個(gè)普通類(lèi),可以創(chuàng)建對(duì)象,調(diào)用方法
(2)如果子類(lèi)還是無(wú)法實(shí)現(xiàn)抽象方法,那么此時(shí)子類(lèi)依然是一個(gè)抽象類(lèi),就仍然需要它的子類(lèi)進(jìn)一步去實(shí)現(xiàn)
代碼示例
public class Demo02_AbstractClassAndInstance {public static void main(String[] args) {Employee c = new Coder();c.work(); } }abstract class A { public abstract void test1(); public abstract void test2();}abstract class C extends A {@Override public void test1() { }}class D extends C {@Override public void test2() { }}class B extends A {@Override public void test1() { }@Override public void test2() { }}abstract class Employee {public abstract void work();}/*** 開(kāi)發(fā)部門(mén)員工類(lèi)* * DevelopmentEmployee* * @author Zihuatanejo* */ abstract class DevEmp extends Employee {}class Coder extends DevEmp {@Override public void work() {System.out.println("敲代碼"); } }class Manager extends DevEmp {@Override public void work() {System.out.println("控制項(xiàng)目進(jìn)度"); }}
(四)抽象類(lèi)成員的特點(diǎn)
1、成員變量:可以有成員變量。子類(lèi)最終是一個(gè)非抽象類(lèi),所以成員變量用于給子類(lèi)繼承。
2、構(gòu)造方法:有
(1)雖然抽象類(lèi)無(wú)法創(chuàng)建對(duì)象,但是抽象類(lèi)需要被子類(lèi)實(shí)現(xiàn),并且抽象類(lèi)具有成員變量,成員變量需要被賦值
(2)子類(lèi)可以創(chuàng)建對(duì)象,子類(lèi)的構(gòu)造需要訪問(wèn)父類(lèi)的構(gòu)造,父類(lèi)構(gòu)造需要給成員變量賦值
3、成員方法:有
(1)可以是抽象方法,可以是非抽象方法
(2)非抽象方法子類(lèi)可以直接繼承使用,抽象方法子類(lèi)需要進(jìn)行實(shí)現(xiàn)(重寫(xiě))
代碼示例
public class Demo03_AboutAbstract {public static void main(String[] args) {} }abstract class Test { private int num;public Test(int num) {this.num = num; }}總結(jié)
以上是生活随笔為你收集整理的面向对象--多态,接口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 第二个
- 下一篇: #章节四:input()函数