面向?qū)ο筇卣鞯恼f明
面向?qū)ο筇攸c(diǎn):封裝裂明、繼承、多態(tài)太援。(如果要回答四個闽晦,可加上抽象性這一特點(diǎn))
- 繼承性:
繼承是一種聯(lián)結(jié)類的層次模型,并且允許和鼓勵類的重用仙蛉,它提供了一種明確表述共性的方法。對象的一個新類可以從現(xiàn)有的類中派生捅儒,這個過程稱為類繼承。新類繼承了原始類的特性鞭莽,新類稱為原始類的派生類(子類)麸祷,而原始類稱為新類的基類(父類)澎怒。派生類可以從它的基類那里繼承方法和實(shí)例變量阶牍,并且類可以修改或增加新的方法使之更適合特殊的需要。
- 繼承性:
- 封裝性:
封裝是把過程和數(shù)據(jù)包圍起來惧辈,對數(shù)據(jù)的訪問只能通過已定義的界面磕瓷。面向?qū)ο笥?jì)算始于這個基本概念,即現(xiàn)實(shí)世界可以被描繪成一系列完全自治困食、封裝的對象,這些對象通過一個受保護(hù)的接口訪問其他對象符匾。
- 封裝性:
- 多態(tài)性:
多態(tài)性是指允許不同類的對象對同一消息作出響應(yīng)瘩例。多態(tài)性包括參數(shù)化多態(tài)性和包含多態(tài)性。多態(tài)性語言具有靈活垛贤、抽象、行為共享南吮、代碼共享的優(yōu)勢琳彩,很好的解決了應(yīng)用程序函數(shù)同名問題誊酌。
- 多態(tài)性:
- 抽象性:
抽象就是忽略一個主題中與當(dāng)前目標(biāo)無關(guān)的那些方面露乏,以便更充分地注意與當(dāng)前目標(biāo)有關(guān)的方面涂邀。抽象并不打算了解全部問題,而只是選擇其中的一部分比勉,暫時不用部分細(xì)節(jié)浩聋。抽象包括兩個方面,一是過程抽象衣洁,二是數(shù)據(jù)抽象。
- 抽象性:
1. 封裝性:
1.1 為什么需要封裝砖第?封裝的作用和含義环凿?
- 追求“高內(nèi)聚,低耦合”智听。
- 高內(nèi)聚 :類的內(nèi)部數(shù)據(jù)操作細(xì)節(jié)自己完成,不允許外部干涉忽洛;
- 低耦合 :僅對外暴露少量的方法用于使用环肘。
- 隱藏對象內(nèi)部的復(fù)雜性,只對外公開簡單的接口悔雹。便于外界調(diào)用,從而提高系統(tǒng)的可擴(kuò)展性梯找、可維護(hù)性益涧。通俗的說,把該隱藏的隱藏起來久免,該暴露的暴露出來。這就是封裝性的設(shè)計(jì)思想阎姥。
1.2 信息的封裝和隱藏
Java中通過將數(shù)據(jù)聲明為私有的(private),再提供公共的(public)方法:get()和set()實(shí)現(xiàn)對該屬性的操作泽腮,以實(shí)現(xiàn)下述目的:
- 隱藏一個類中不需要對外提供的實(shí)現(xiàn)細(xì)節(jié)衣赶;
- 使用者只能通過事先定制好的方法來訪問數(shù)據(jù),可以方便地加入控制邏輯府瞄,限制對屬性的不合理操作;
- 便于修改续崖,增強(qiáng)代碼的可維護(hù)性
代碼示例:
class A {
private int num = 0;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
public class Example {
public static void main(String[] args) {
A a = new A();
System.out.println(String.format("num: %d", a.getNum()));
a.setNum(1);
System.out.println(String.format("num: %d", a.getNum()));
}
}
輸出:
num: 0
num: 1
1.3 四種訪問權(quán)限修飾符
- Java權(quán)限修飾符public团搞、protected、(缺省)像吻、private置于類的成員定義前复隆, 用來限定對象對該類成員的訪問權(quán)限。
- 對于class的權(quán)限修飾只可以用public和default(缺省)惭每。
- public類可以在任意地方被訪問亏栈。
- default類只可以被同一個包內(nèi)部的類訪問。
修飾符 | 類內(nèi)部 | 同一個包 | 不同包的子類 | 同一個工程 |
---|---|---|---|---|
private | Yes | |||
(缺省) | Yes | Yes | ||
protected | Yes | Yes | Yes | |
public | Yes | Yes | Yes | Yes |
2. 繼承性:
2.1 為什么要有繼承绒北?
- 多個類中存在相同屬性和行為時,將這些內(nèi)容抽取到單獨(dú)一個類中峻汉,那么多個類無需再定義這些屬性和行為,只要繼承那個類即可休吠。(此處的多個類稱為子類(派生類)蛛碌,單獨(dú)的這個類稱為父類(基類或超類)辖源。可以理解為:“子類 is a 父類”)
2.2 類繼承語法規(guī)則:
class Subclass extends SuperClass{}
2.3子類與父類
- 子類繼承了父類克饶,就繼承了父類的方法和屬性。
- 在子類中亡脑,可以使用父類中定義的方法和屬性邀跃,也可以創(chuàng)建新的數(shù)據(jù)和方法。
- 在Java中拍屑,繼承的關(guān)鍵字用的是“extends”,即子類不是父類的子集喷斋,而是對父類的“擴(kuò)展”蒜茴。
2.4繼承規(guī)則
- 子類不能直接訪問父類中私有的(private)的成員變量和方法。
- Java只支持單繼承和多層繼承顽腾,不允許多重繼承 :
- 一個子類只能有一個父類
- 一個父類可以派生出多個子類
2.5方法的重寫
在子類中可以根據(jù)需要對從父類中繼承來的方法進(jìn)行改造诺核,也稱為方法的重置、覆蓋猪瞬。在程序執(zhí)行時,子類的方法將覆蓋父類的方法
要求:
- 子類重寫的方法必須和父類被重寫的方法具有**相同的方法名稱幌甘、參數(shù)列表 **。
- 子類重寫的方法的返回值類型不能大于父類被重寫的方法的返回值類型 锅风。
- 子類重寫的方法使用的訪問權(quán)限不能小于父類被重寫的方法的訪問權(quán)限 皱埠。
子類不能重寫父類中聲明為private權(quán)限的方法 。 - 子類方法拋出的異常不能大于父類被重寫方法的異常 边器。
注意:
子類與父類中同名同參數(shù)的方法必須同時聲明為非static的(即為重寫),或者同時聲明為 static的(不是重寫)恒界。因?yàn)閟tatic方法是屬于類的砚嘴,子類無法覆蓋父類的方法。
class Person {
String name = "person";
private int age = 18;
String getinfo() {
return String.format("name: %s age: %d %n", name, age);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Student extends Person {
String name = "student";
String school = "school";
String getinfo() {
return String.format("name: %s age: %d school: %s%n", name, getAge(), school);
}
}
public class InheritDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p = new Person();
System.out.println(p.getinfo());
Student s = new Student();
System.out.println(s.getinfo());
}
}
輸出:
name: person age: 18
name: student age: 18 school: school
2.6 作用:
1. 繼承的出現(xiàn)減少了代碼冗余耸采,提高了代碼的復(fù)用性工育。
1. 繼承的出現(xiàn),更有利于功能的擴(kuò)展翅娶。
1. 繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系竭沫,提供了多態(tài)的前提。
- 注意:不要僅為了獲取其他類中某個功能而去繼承
3. 多態(tài)性
對象的多態(tài)性在Java中的體現(xiàn):
父類的引用指向子類的對象 (可以直接應(yīng)用在抽象類和接口上)
Java引用變量有兩個類型:編譯時類型和運(yùn)行時類型蜕提。
編譯時類型由聲明該變量時使用的類型決定,運(yùn)行時類型由實(shí)際賦給該變量的對象決定凛膏。
簡稱:編譯時脏榆,看左邊;運(yùn)行時须喂,看右邊趁蕊。
若編譯時類型和運(yùn)行時類型不一致仔役,就出現(xiàn)了對象的多態(tài)性。
“看左邊”:看的是父類的引用(父類中不具備子類特有的方法)
“看右邊”:看的是子類的對象(實(shí)際運(yùn)行的是子類重寫父類的方法)
對象的多態(tài) 在Java中,子類的對象可以替代父類的對象使用 :
一個變量只能有一種確定的數(shù)據(jù)類型
一個引用類型變量可能指向(引用)多種不同類型的對象 Person p = new Student();
子類可看做是特殊的父類任柜,所以父類類型的引用可以指向子類的對象:向上轉(zhuǎn)型(upcasting)沛厨。
一個引用類型變量如果聲明為父類的類型,但實(shí)際引用的是子類對象,那么該變量就不能再訪問子類中添加的屬性和方法
示例代碼:
abstract class Animal {
String name = "animal";
public abstract String getinfo();
}
class Cat extends Animal {
String name = "cat";
int age = 3;
public String getinfo() {
return String.format("name: %s age: %d", name, age);
}
void sleep() {
System.out.println("The cat is asleep under the table.");
}
}
public class PolymorphicDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
String info;
Cat c = new Cat();
info = String.format("c:%nname: %s. %ninfo: %s", c.name, c.getinfo());
System.out.println(info);
c.sleep();
System.out.println();
Animal a = c;
info = String.format("a:%nname: %s. %ninfo: %s", a.name, a.getinfo());
System.out.println(info);
// a.sleep() 無效页屠,父類沒有sleep()方法
System.out.println();
Cat c1 = (Cat) a;
info = String.format("c1:%nname: %s. %ninfo: %s", c1.name, c1.getinfo());
System.out.println(info);
c.sleep();
System.out.println(String.format("c與c1是否為同一地址: %b", c1 == c));
}
}
輸出:
c:
name: cat.
info: name: cat age: 3
The cat is asleep under the table.
a:
name: animal.
info: name: cat age: 3
c1:
name: cat.
info: name: cat age: 3
The cat is asleep under the table.
c與c1是否為同一地址: true
多態(tài)小結(jié)
- 多態(tài)作用:
提高了代碼的通用性蓖柔,常稱作接口重用 - 前提:
需要存在繼承或者實(shí)現(xiàn)關(guān)系
有方法的重寫 - 成員方法:
編譯時:要查看引用變量所聲明的類中是否有所調(diào)用的方法。
運(yùn)行時:調(diào)用實(shí)際new的對象所屬的類中的重寫方法牢贸。 - 成員變量:
不具備多態(tài)性镐捧,只看引用變量所聲明的類。