對象關係的研究
1.繼承關係
code:
public class 繼承關係 {
public static void main(String[] args) {
BMW bmw = new BMW();
//BWM類所創建的對象擁有父類Car的所有實例成員
bmw.beautiful();
bmw.driving();
bmw.engine();
bmw.wheel();
}
}
class Car{//汽車類
void engine(){//發動機
}
void wheel(){//車輪
}
}
class BMW extends Car{//寶馬車,擁有汽車類的所有屬性並且擁有自己的特有屬性
void beautiful(){//美麗的外表
}
void driving(){//強勁的動力
}
}
繼承的概述:
- 被繼承的類被稱爲父類(超類),由繼承而得到的新類被稱爲子類
- 父類可以是Java類庫中的類,也可以是自己寫的類
- 一個子類是父類的特定版本,它繼承了父類所有的實例變量和方法,同時添加了自己的特有屬性
- Java不支持多重繼承,即子類只能有一個父類
- 使用extends 關鍵字實現繼承
- 如果一個類的聲明中沒有使用extends關鍵字,那麼這個類默認繼承Object類
子類的繼承性:
- 子類和父類在同一個包中時,子類不能訪問聲明爲private的父類成員(私有成員)
- 子類和父類不在同一個包中時,那麼子類只能繼承父類聲明爲protected和public的成員,不能繼承私有成員和友好成員
2.關聯關係
code:
public class 關聯關係 {
}
class Book{
int id;
String name;
BookExtend bookExtend = new BookExtend();//Book類引用了一個類型爲被關聯類BookExtend的全局變量
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BookExtend getBookExtend() {
return bookExtend;
}
public void setBookExtend(BookExtend bookExtend) {
this.bookExtend = bookExtend;
}
}
class BookExtend{
int id;
String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
關聯關係:
體現的是兩個類、或者類與接口之間語義級別的一種強依賴關係,比如我和我的朋友;這種關係比依賴更強、不存在依賴關係的偶然性、關係也不是臨時性的,一般是長期性的,而且雙方的關係一般是平等的、關聯可以是單向、雙向的;表現在代碼層面,爲被關聯類B以類屬性的形式出現在關聯類A中,也可能是關聯類A引用了一個類型爲被關聯類B的全局變量;
3.聚合與組合
code:
public class 聚合與組合 {
}
class GooseGroup{//雁羣類
public Goose goose;
public int amount;
public GooseGroup(Goose goose){//大雁類的構造函數
this.goose = goose;
}
void show() {
System.out.println("這是一個大雁羣,共有"+amount+"只大雁");
}
public Goose getGoose() {
return goose;
}
public void setGoose(Goose goose) {
this.goose = goose;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
class Goose{//大雁類
public Wings wings;
public void show(){
System.out.println("我是一隻自由的大雁");
}
public Goose(){//大雁類的構造函數
wings = new Wings();
}
public Wings getWings() {
return wings;
}
public void setWings(Wings wings) {
this.wings = wings;
}
}
class Wings{//翅膀類
public void show(){
System.out.println("我有豐滿的羽翼");
}
}
代碼分析:
- 聚合關係的類裏含有另一個類作爲參數
雁羣類(GooseGroup)的構造函數中要用到大雁(Goose)作爲參數把值傳進來 大雁類(Goose)可以脫離雁羣類而獨立存在 - 組合關係的類裏含有另一個類的實例化
大雁類(Goose)在實例化之前 一定要先實例化翅膀類(Wings) 兩個類緊密耦合在一起 它們有相同的生命週期 翅膀類(Wings)不可以脫離大雁類(Goose)而獨立存在 - 信息的封裝性不同
在聚合關係中,客戶端可以同時瞭解雁羣類和大雁類,因爲他們都是獨立的
而在組合關係中,客戶端只認識大雁類,根本就不知道翅膀類的存在,因爲翅膀類被嚴密的封裝在大雁類中。
- 聚合關係
聚合是關聯關係的一種特例,他體現的是整體與部分、擁有的關係,即has-a的關係,此時整體與部分之間是可分離的,他們可以具有各自的生命週期,部分可以屬於多個整體對象,也可以爲多個整體對象共享;比如計算機與CPU、公司與員工的關係等;表現在代碼層面,和關聯關係是一致的,只能從語義級別來區分; - 組合關係
組合也是關聯關係的一種特例,他體現的是一種contains-a的關係,這種關係比聚合更強,也稱爲強聚合;他同樣體現整體與部分間的關係,但此時整體與部分是不可分的,整體的生命週期結束也就意味着部分的生命週期結束;比如你和你的大腦;表現在代碼層面,和關聯關係是一致的,只能從語義級別來區分; - 總體比較
幾種關係所表現的強弱程度依次爲:組合>聚合>關聯;
聚合跟組合其實都屬於關聯 只不過它們是兩種特殊的關聯 因爲本是同根生 所以它們之間難免會有相似之處
4.繼承下的方法重寫
code:
public class 繼承下的方法重寫 {
}
//方法的重寫、使用super調用父類的構造器
class test1{
public static void main(String[] args) {
B b = new B();//通過B類的構造函數創建對象,先調用父類A的含參構造器,然後執行了smile和cry方法
System.out.println();
C c = new C();//通過C類的構造器創建對象,先調用父類A的無參構造器,然後打印一句話
}
}
class A{
A(){
System.out.println("所調用的是A類中不帶參數的構造器");
}
A(int a){
System.out.println("所調用的是A類中帶參數的構造器");
}
void smile(){
System.out.println("我開心的笑了");
}
void cry(){
System.out.println("我這次真的傷心了");
}
}
class B extends A{
B(){//無參構造函數
super(10);//用super關鍵字調用父類帶參數的構造方法
System.out.println("我是類B,我繼承了A");
smile();//調用的是重寫過後的方法
cry();//調用的是從父類繼承的cry方法
}
void smile(){//重寫smile方法
System.out.println("看!我在傻傻的笑!");
}
}
class C extends A{
C(){//默認調用父類的無參構造器 相當於“ super(); ”
System.out.println("我是類C,我繼承了類A");
}
}
//使用super操作被隱藏的成員變量和方法
class test2{
public static void main(String[] args) {
E e = new E();
e.smile();
}
}
class D{
int a = 10;
D(){
System.out.println("我是類D,我被E繼承了");
}
void smile(){
System.out.println("我是類A的smile方法");
}
}
class E extends D{
int a;
int b;
E(){//"super();"默認調用父類無參構造器
System.out.println("我是類E的a變量,"+a);
b = super.a;//利用super操作被隱藏的變量a
System.out.println("我是類E的b變量,"+b);
}
void smile(){
super.smile();//利用super操作被隱藏的smile方法
System.out.println("我是類E的smile方法");
}
}
test1 輸出臺:
所調用的是A類中帶參數的構造器
我是類B,我繼承了A
看!我在傻傻的笑!
我這次真的傷心了
所調用的是A類中不帶參數的構造器
我是類C,我繼承了類A
Process finished with exit code 0
test2 輸出臺:
我是類D,我被E繼承了
我是類E的a變量,0
我是類E的b變量,10
我是類A的smile方法
我是類E的smile方法
Process finished with exit code 0
- 方法重寫
- 子類中定義一個方法,並且這個方法的名字、返回類型、參數類型及參數的個數與父類繼承的方法完全相同。
- 通過方法重寫,子類可以把父類得狀態轉變成自己的狀態和行爲。
- 一旦方法重寫成功,所繼承的父類的方法會被隱藏,子類如果調用嗎、,則會調用重寫後的方法。
- 如果子類想要使用被隱藏的方法,必須使用super關鍵字。
- super關鍵字
- 使用super調用父類的構造方法
- 子類不繼承父類的構造方法。如果想要調用,可以使用super,但super語句必須是子類構造方法中的第一條語句。
- 子類在創建對象時,子類的構造方法總是調用父類的某個構造方法。
如果父類有多個構造方法,那麼子類默認調用的是那個不帶參數的
如果父類只有一個帶參數的構造方法,那麼在子類中必須在自己的構造方法中使用super語句來調用父類帶參數的構造方法,否則報錯 - 如果子類的構造方法中,沒有super語句,那麼系統默認有“super();”存在,即調用父類的不帶參數的構造方法
- 使用super操作被隱藏的父類的成員變量和方法
- 只有使用super關鍵字才能訪問被隱藏的變量和方法
5.Java多態實現
code:
public class Java多態實現 {
}
class Animal{
Animal(){
System.out.println("貓、狗都是動物");
}
void eat(){
System.out.println("動物都要吃東西");
}
void run(){
System.out.println("動物都會跑");
}
}
class Dog extends Animal {
void eat() {
System.out.println("狗愛吃骨頭");
}
}
class Test{
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.eat();
Dog dog2 = new Dog();
Animal animal;
animal = dog2;//多態性
animal.eat();//dog2有eat方法就調用Dog類方法
animal.run();//dog2沒有run方法就調用Animal方法
}
}
輸出臺·:
貓、狗都是動物
狗愛吃骨頭
貓、狗都是動物
狗愛吃骨頭
動物都會跑
Process finished with exit code 0
Java多態實現:
- 多態性是指不同類的對象對同一消息做出響應。
- 包括參數多態性和包含多態性。
- 當我們將子類對象的引用傳給聲明爲父類的一個對象變量,如果子類
6.final方法
code:
public class final方法 {
}
final class FinalClass{//final類
}
//class ClassOne extends FinalClass{ 非法,final類無法被繼承
//
//}
class ClassTwo{
final int a=10;//final變量
final void test(){//final方法
int b = 10;
}
}
class ClassThree extends ClassTwo {
// void test(){ 非法,final方法不可被重寫
// }
// a=10; 非法,final變量不可被修改
}
final方法:
- 以final修飾的成員變量,對象雖然可以操作使用它,但不你對它進行更改更改操作
- 以final修飾的類,不可以被繼承,即final類沒有子類(出於安全性的考慮)
- final修飾的方法不可以被子類重寫,同時,final方法的行爲是不允許子類更改的
7.Object類
code:
public class Object類 {
}
class Otest{
private String username = "system";
private String passward = "manager";
Otest(String name,String pwd){
if (name.equals(null)||pwd.equals(null)) {
System.out.println("用戶名或密碼爲空!");
} else {
if (username.equals(name)&&pwd.equals(pwd)) {
System.out.println("登錄成功!");
} else {
System.out.println("登錄失敗!");
}
}
}
public static void main(String[] args) {
Otest otest = new Otest("system","manager");
}
}
輸出臺:
登錄成功!
Process finished with exit code 0
Object類:
- Object類是多有類的父類,即Java中的沒一個類都是由Object類擴展而來
- Object類的方法和用途
方法 | 用途 |
---|---|
Object clone | 創建與該對象的類相同的新對象 |
Boolean equals(Object) | 比較兩對象是否相等 |
void finalize() | 當垃圾回收器確定不存在對該對象的更多引用時,對象的垃圾回收器調用該方法 |
class getClass() | 返回一個對象的運行時間類 |
int hasCode | 返回該對象的散列碼值 |
void notify() | 激活等待在該對象的監視器上的一個進程 |
String toString() | 返回該對象的字符串表示 |
void wait() | 等待這個對象另一個更改線程的通知 |
void wait(long,int) | 等待這個對象另一個更改線程的通知 |
- Object類提供的只是一些基本的方法,我們在編寫自己的類時經常需要覆蓋這些方法,一方面是加強功能,另一方發麪是爲了適應當前的情況