java学习笔记6--类的继承、Object类
接著前面的學(xué)習(xí):
java學(xué)習(xí)筆記5--類的方法?
java學(xué)習(xí)筆記4--類與對(duì)象的基本概念(2)
java學(xué)習(xí)筆記3--類與對(duì)象的基本概念(1)
java學(xué)習(xí)筆記2--數(shù)據(jù)類型、數(shù)組
java學(xué)習(xí)筆記1--開發(fā)環(huán)境平臺(tái)總結(jié)
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note6.html,轉(zhuǎn)載請(qǐng)注明源地址。
1、類的繼承
一種由已有的類創(chuàng)建新類的機(jī)制,是面向?qū)ο蟪绦蛟O(shè)計(jì)的基石之一。通過繼承,可以根據(jù)已有類來定義新類,新類擁有已有類的所有功能
Java只支持單繼承,每個(gè)子類只能有一個(gè)直接父類,父類是所有子類的公共屬性及方法的集合,子類則是父類的特殊化,繼承機(jī)制可以提高程序的抽象程度,提高代碼的可重用性
基類(base class),也稱超類(superclass),是被直接或間接繼承的類
派生類(derived-class),也稱子類 (subclass),繼承其他類而得到的類,繼承所有祖先的狀態(tài)和行為。派生類可以增加變量和方法,派生類也可以覆蓋(override)繼承的方法
子類對(duì)象與父類對(duì)象存在“IS A”(或“is kind of”)的關(guān)系
派生類產(chǎn)生的對(duì)象,從外部來看,它應(yīng)該包括與基類相同的接口,可以具有更多的方法和數(shù)據(jù)成員,其內(nèi)包含著一個(gè)基類類型的子對(duì)象
繼承的語法: class childClass extends parentClass {//類體 }舉個(gè)例子:
在一個(gè)公司中,有普通員工(Employees)及管理人員(Magagers)兩類人員:
職員對(duì)象(Employees)可能有的屬性信息包括:
–員工號(hào)(employeeNumber)
–姓名(name)
–地址(address)
–電話號(hào)碼(phoneNumber)
管理人員(Managers)除具有普通員工的屬性外,還可能具有下面的屬性:
–職責(zé)(responsibilities)
–所管理的職員(listOfEmployees)
Employee與Manager的類圖: //父類Employee class Employee { int employeeNumbe ;String name, address, phoneNumber ; } //子類Manager class Manager extends Employee {//子類增加的數(shù)據(jù)成員 String responsibilities, listOfEmployees; }設(shè)有三個(gè)類:Person, Employee, Manager。其類層次如圖:
public class Person {public String name;public String getName() { return name; } } public class Employee extends Person { public int employeeNumber; public int getEmployeeNumber() { return employeeNumber; } } public class Manager extends Employee { public String responsibilities; public String getResponsibilities() { return responsibilities;} }測(cè)試程序:
public class Test {public static void main(String args[]){Employee li = new Employee(); li.name = "Li Ming"; li.employeeNumber = 123456; System.out.println(li.getName());System.out.println(li.getEmployeeNumber()); Manager he = new Manager(); he.name = "He Xia"; he.employeeNumber = 543469; he.responsibilities = "Internet project"; System.out.println(he.getName()); System.out.println(he.getEmployeeNumber());System.out.println(he.getResponsibilities());} } 運(yùn)行結(jié)果:Li Ming
123456
He Xia
543469
Internet project
說明:子類不能直接訪問從父類中繼承的私有屬性及方法,但可使用公有(及保護(hù))方法進(jìn)行訪問,如下例所示:
public class B { public int a = 10; private int b = 20; protected int c = 30; public int getB() { return b; } } public class A extends B { public int d; public void tryVariables() { System.out.println(a); //允許 System.out.println(b); //不允許System.out.println(getB()); //允許 System.out.println(c); //允許 } }隱藏和覆蓋
子類對(duì)從父類繼承來的屬性變量及方法可以重新定義,來看一個(gè)簡(jiǎn)單的例子:
class Parent {Number aNumber; } class Child extends Parent {Float aNumber; }屬性的隱藏:
子類中聲明了與父類中相同的成員變量名,則從父類繼承的變量將被隱藏
子類擁有了兩個(gè)相同名字的變量,一個(gè)繼承自父類,另一個(gè)由自己聲明,當(dāng)子類執(zhí)行繼承自父類的操作時(shí),處理的是繼承自父類的變量,而當(dāng)子類執(zhí)行它自己聲明的方法時(shí),所操作的就是它自己聲明的變量
如何訪問被隱藏的父類屬性?
調(diào)用從父類繼承的方法,則操作的是從父類繼承的屬性,使用super.屬性
屬性的隱藏舉例:
class A1 {int x = 2; public void setx(int i){ x = i;}void printa(){System.out.println(x);} } class B1 extends A1 {int x = 100;void printb() {super.x = super.x + 10 ;System.out.println("super.x= " + super.x + " x= " + x);} }測(cè)試程序:
public class Test {public static void main(String[] args){A1 a1 = new A1(); a1.setx(4); a1.printa();B1 b1 = new B1(); b1.printb(); b1.printa(); b1.setx(6); // 將繼承來的x值設(shè)置為6 b1.printb(); b1.printa();a1.printa();} } 運(yùn)行結(jié)果:4
super.x= 12? x= 100
12
super.x= 16? x= 100
16
4
子類不能繼承父類中的靜態(tài)屬性,但可以對(duì)父類中的靜態(tài)屬性進(jìn)行操作。如在上面的例子中,將“int x = 2;”改為“static int x = 2;”,再編譯及運(yùn)行程序,會(huì)得到下面的結(jié)果方法覆蓋
如果子類不需使用從父類繼承來的方法的功能,則可以聲明自己的同名方法,稱為方法覆蓋。覆蓋方法的返回類型,方法名稱,參數(shù)的個(gè)數(shù)及類型必須和被覆蓋的方法一摸一樣
只需在方法名前面使用不同的類名或不同類的對(duì)象名即可區(qū)分覆蓋方法和被覆蓋方法,覆蓋方法的訪問權(quán)限可以比被覆蓋的寬松,但是不能更為嚴(yán)格
方法覆蓋的應(yīng)用場(chǎng)合:
-
子類中實(shí)現(xiàn)與父類相同的功能,但采用不同的算法或公式
-
在名字相同的方法中,要做比父類更多的事情
-
在子類中需要取消從父類繼承的方法
必須覆蓋的方法
派生類必須覆蓋基類中的抽象的方法,否則派生類自身也成為抽象類.
不能覆蓋的方法
基類中聲明為final的終結(jié)方法
基類中聲明為static 的靜態(tài)方法
調(diào)用被覆蓋的方法
super.overriddenMethodName();
有繼承時(shí)的構(gòu)造方法遵循以下的原則:
子類不能從父類繼承構(gòu)造方法
好的程序設(shè)計(jì)方法是在子類的構(gòu)造方法中調(diào)用某一個(gè)父類構(gòu)造方法,調(diào)用語句必須出現(xiàn)在子類構(gòu)造方法的第一行,可使用super關(guān)鍵字
如子類構(gòu)造方法的聲明中沒有明確調(diào)用父類構(gòu)造方法,則系統(tǒng)在執(zhí)行子類的構(gòu)造方法時(shí)會(huì)自動(dòng)調(diào)用父類的默認(rèn)構(gòu)造方法(即無參的構(gòu)造方法)
舉一個(gè)例子:
public class Person { protected String name, phoneNumber, address; public Person() { this("", "", "");} public Person(String aName, String aPhoneNumber, String anAddress) { name=aName; phoneNumber=aPhoneNumber; address=anAddress;} } public class Employee extends Person { protected int employeeNumber; protected String workPhoneNumber;?public Employee(){ //此處隱含調(diào)用構(gòu)造方法 Person() this(0, "");} public Employee(int aNumber, String aPhoneNumber){ //此處隱含調(diào)用構(gòu)造方法 Person() employeeNumber=aNumber; workPhoneNumber = aPhoneNumber;} } public class Professor extends Employee { protected String research; public Professor(){ super(); research = ""; } public Professor(int aNumber, String aPhoneNumber, String aResearch) { super(aNumber, aPhoneNumber); research = aResearch; } }2、Object類
Java程序中所有類的直接或間接父類,類庫中所有類的父類,處在類層次最高點(diǎn),包含了所有Java類的公共屬性,其構(gòu)造方法是Object( )
Object類定義了所有對(duì)象必須具有的狀態(tài)和行為,較主要的方法如下
–public final Class getClass()?
獲取當(dāng)前對(duì)象所屬的類信息,返回Class對(duì)象
–public String toString()
返回當(dāng)前對(duì)象本身的有關(guān)信息,按字符串對(duì)象返回
–public boolean equals(Object obj)?
比較兩個(gè)對(duì)象是否是同一對(duì)象,是則返回true
–protected Object clone( )?
生成當(dāng)前對(duì)象的一個(gè)拷貝,并返回這個(gè)復(fù)制對(duì)象
–Public int hashCode()??
返回該對(duì)象的哈希代碼值
–protected void finalize() throws Throwable
定義回收當(dāng)前對(duì)象時(shí)所需完成的資源釋放工作
你的類不可以覆蓋終結(jié)方法,即有final修飾的方法
相等和同一的概念
兩個(gè)對(duì)象具有相同的類型,及相同的屬性值,則稱二者相等(equal)
如果兩個(gè)引用變量指向的是同一個(gè)對(duì)象,則稱這兩個(gè)變量(對(duì)象)同一(identical)
兩個(gè)對(duì)象同一,則肯定相等;兩個(gè)對(duì)象相等,不一定同一
比較運(yùn)算符“==” 判斷的是這兩個(gè)對(duì)象是否同一
//判斷兩個(gè)對(duì)象是否同一 public class test{public static void main(String args[]){BankAccount a = new BankAccount("Bob", 123456, 100.00f); BankAccount b = new BankAccount("Bob", 123456, 100.00f); if (a == b) System.out.println("YES"); else System.out.println("NO");} }equals 方法
由于Object是類層次結(jié)構(gòu)中的樹根節(jié)點(diǎn),因此所有其他類都繼承了equals()方法。Object類中的 equals() 方法的定義如下,可見,也是判斷兩個(gè)對(duì)象是否同一
public boolean equals(Object x) { return this == x; }Object類中equals方法的使用舉例:
public class EqualsTest{public static void main(String args[]){BankAccount a = new BankAccount("Bob", 123456, 100.00f); BankAccount b = new BankAccount("Bob", 123456, 100.00f); if (a.equals(b))System.out.println("YES"); else System.out.println("NO");} }在BankAccount類中增加equals方法,由于是對(duì)Object類中的equals方法進(jìn)行重寫,因此方法定義頭必須與Object類中的equals方法完全相同
public boolean equals(Object x) { if (this.getClass() != x.getClass()) return false; BankAccount b = (BankAccount)x; return ((this.getOwnerName().equals(b.getOwnerName())) &&(this.getAccountNumber() == b.getAccountNumber())&&(this.getBalance() == b.getBalance())); }equals方法的應(yīng)用舉例:
public class Apple { private String color; private boolean ripe; public Apple(String aColor, boolean isRipe) { color = aColor; ripe = isRipe; } public void setColor(String aColor) { color = aColor; } public void setRipe(boolean isRipe) { ripe = isRipe; } public String getColor() { return color; } public boolean getRipe() { return ripe; }public String toString() { if (ripe) return("A ripe " + color + " apple"); else return("A not so ripe " + color + " apple"); } public boolean equals(Object obj) { if (obj instanceof Apple) { Apple a = (Apple) obj; return (color.equals(a.getColor()) && (ripe == a.getRipe())); } return false; } } 運(yùn)行結(jié)果:A ripe red apple is equal to A ripe red apple: true
a is identical to b: false
A ripe red apple is equal to A ripe red apple: true
a is identical to c: true
Clone方法根據(jù)已存在的對(duì)象構(gòu)造一個(gè)新的對(duì)象;?在根類Object 中被定義為protected,所以需要覆蓋為public;?實(shí)現(xiàn)Cloneable 接口,賦予一個(gè)對(duì)象被克隆的能力(cloneability)
class MyObject implements Cloneable { //… }finalize方法
在對(duì)象被垃圾回收器回收之前,系統(tǒng)自動(dòng)調(diào)用對(duì)象的finalize方法;?如果要覆蓋finalize方法,覆蓋方法的最后必須調(diào)用super.finalize
getClass方法
final 方法,返回一個(gè)Class對(duì)象,用來代表對(duì)象隸屬的類
通過Class 對(duì)象,你可以查詢Class對(duì)象的各種信息:比如它的名字,它的基類,它所實(shí)現(xiàn)接口的名字等。
void PrintClassName(Object obj) {System.out.println("The Object's class is " + obj.getClass().getName()); }notify、notifyAll、wait方法
final方法,不能覆蓋,這三個(gè)方法主要用在多線程程序中
參考資料:
《java程序設(shè)計(jì)》--清華大學(xué)
作者:wuyudong 出處:http://www.cnblogs.com/wuyudong/總結(jié)
以上是生活随笔為你收集整理的java学习笔记6--类的继承、Object类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java学习笔记5--类的方法
- 下一篇: java学习笔记7--抽象类与抽象方法