天天看點

Java個人學習筆記心得之面向對象

構造器(構造方法)

方法名和類名一樣,但是沒有傳回值,void也不能加

**最好:**一個類如果重寫了有參構造,那麼最好機上一個無參構造,如果不加,可能會在繼承關系中出錯

作用:

  1. 使用new關鍵字,必須要有構造器(本質是在調用構造器)
  2. 一旦定義了一個有參構造,那麼無參構造必須顯示定義
  3. 一般用來初始化值

文法:

public class hello {
    public String _name;
    private int _age;
    //構造器,也叫構造方法
    public hello(String name, int age) {
        this._name = name;
        this._age = age;
    }
}
           

在這裡,_age是私有的,哪怕在構造器賦了值,在别的類中建立對象也還是調用不了,而 _name就可以

面向對象三大特性:

(有繼承才有重寫,有重寫才有多态)

封裝:

意義:

  • 提高程式的安全性,保護資料
  • 隐藏代碼的實作細節
  • 統一接口
  • 系統可維護性增加

封裝(資料的隐藏):

通常,應禁止直接通路一個對象中的資料的實際表示,而應通過操作接口來通路,這成為資訊隐藏

記住這句話就夠了:屬性私有,get/set

示例:

在hello這個類中給它的屬性封裝:

public class hello {
    //屬性私有
    private String name;
    private int age;
    //提供一些可以操作這個屬性的方法
    //提供一些public的get和set方法

    //封裝的get方法,傳回值為封裝屬性的類型,且封裝屬性的首字母大寫
    //get 獲得傳回的這個資料
    public String getName(){
        return this.name;
    }
    //封裝的set方法,傳回值為void,提供給外部進行的操作,屬性首字母大寫
    //set 給這個屬性設定值,也可以加上條件對不合法的起輸入限制作用
    public void setName(String name){
        this.name =name;
       }
}
           

在另一個類中,執行個體化hello類的對象,調用它的封裝屬性:

hello h= new hello();
 h.setName("王志凱");//在另一個類通過設定的方法給屬性設值
 System.out.println(h.getName());//得到傳回的值,并且輸出
           

結果:

王志凱

繼承:

在Java中所有的類都是object的子類。預設繼承object類

在Java中類隻能單繼承,沒有多繼承

文法:

extends:擴充。子類是父類的擴充

public class Student extends Person {
}
           

super:

注意點:

  • super調用父類的構造方法,必須在構造方法的第一個
  • super必須隻能出現在子類的方法和或者構造方法中
  • super和this不能同時調用構造方法

super VS this

  • 代表的對象不同

this:本身調用者這個對象

super:代表父類對象的應用

前提:

this:沒有繼承也可以使用

super:隻能在繼承條件下才能使用

構造方法的差別:

this():調用本類的構造方法

super():調用父類的構造方法

重寫(override):

重寫就是在子類裡建立一個和父類中相同的方法,但是裡面的方法體不同,這樣子,在對象調用的時候,就會調用到子類重寫的方法,而不會調用到父類的相同的方法

  1. 需要有繼承關系,子類重寫父類的方法
  2. 方法名必須相同,方法體可以不同
  3. 參數清單必須相同
  4. 修飾符:範圍可擴大,public>Protected>Default>private
  5. 抛出的異常:範圍,可以被縮小,但不能擴大:ClassNotFoundException–>Exception
  6. 重寫都是方法的重寫,和屬性無關,私有的方法無法重寫
  7. 非靜态的方法才能被重寫

靜态方法:方法的調用隻和左邊定義的資料類型有關

**非靜态方法:**才叫重寫

思考:為什麼需要重寫?

答:父類的功能子類不一定需要,或者不一定滿足,是以需要子類把父類的方法重寫一下,加上自己需要的功能

示例:

Application類:

public class Application {
    public static void main(String[] args) {
        Student s = new Student();//重點關注這裡
        s.test();
        Person p = new Student();//重點關注這裡
        p.test();
    }
}
           

Person類:

public class Person {
    public static void test(){

 System.out.println("person的test");
    }
}
           

Student類:

public class Student extends Person {
    public static void test(){

    System.out.println("student的test");
    }
}
           

輸出的結果:

student的test

person的test

**解析:**這說明,當方法是靜态方法的時候,調用方法隻與 Student s 和 Person p有關,也就是說當是靜态方法時,調用的方法隻和執行個體化語句中的:

Student s = new Student();
           
Person p = new Student();
           

左邊相關,是哪個類就是哪個類的方法,否則就是new的類的方法。

多态:

  1. 即同一方法可以根據發送對象的不同采用多種不同的行為方式
  2. 一個對象的 “實際類型”(如:new Person())是确定的,但可以指向對象的 “引用類型”(如:Person p )有很多
  3. 多态存在的條件:
  • 有繼承關系
  • 子類重寫了父類方法
  • 父類的引用指向子類對象
A a= new B();
           

*

注意:

  • 多态是方法的多态,屬性沒有多态性
  • 如果父類的引用類型指向得失子類的對象,那麼通過父類的引用類型來調用的方法還是可以實作父類的功能的,雖然是指向了子類的,但因為子類是繼承了父類的方法的。
  • 靜态方法:方法的調用隻和左邊定義的資料類型有關
  • **非靜态方法:**才能重寫

通俗的說就是:

對象能執行的那些非靜态的方法,主要看對象左邊的類型,和右邊的關系不大,隻有左邊的類型有的非靜态的方法才可以實作,隻有右邊有的方法沒辦法實作。

B a= new B();//B 能調用的方法都是自己的或者繼承父類A的
A a= new B();//A 父類型的引用,可以指向子類,但是不能調用子類獨有的方法。
           

有static靜态,final常量,private私有修飾符的無法重寫,自然也就沒有多态

Instanceof

文法:A Instanceof B

A和B有關系嗎?有true,沒有false

用法:

有一個Student類繼承extends父類Person

Object o = new Student();
 System.out.println(o instanceof Student);
 System.out.println(o instanceof Person);
 System.out.println(o instanceof Object);
 System.out.println(o instanceof String);
           

結果:

true

true

true

false

類型轉換:

高轉低要強制轉換,低轉高自動轉換

父類高于子類

文法:

(Person)Student

Static

當通路的類中的變量是static變量時候,可以直接通過類名.來通路這個成員。

static方法隻會在一開始加載一次,之後不會再加載

抽象類:

  • 抽象類,隻有抽象方法,沒有方法體。
  • 子類如果繼承了抽象類,那麼抽象類的所有方法,子類都要去實作。(如果子類也是abstract,那就不用)

特點:

  • 不能new出來這個抽象類,隻能靠子類去實作它
  • 抽象類隻可以寫方法,沒有方法體
  • 抽象方法必須在抽象類中

個人思考:

抽象類真正的作用是為了實作,他的目的是當父類某種方法毫無意義,但是又必須要有的時候占個位置,提醒子類一定要去實作。打個比方,電器有耗電标準,但是籠統的電器(父類)的耗電标準是毫無意義的,隻有具體到實際的某種電器(子類)才有意義,是以幹脆就不在電器(父類)中寫,由具體的電器(子類)來完成,但是耗電标準又是必須得實作的,是以需要電器(父類)為之提醒。這也是跟實際生活相符合的結果,是面向對象思維的展現。

(****就是當這個父類是抽象類的時候裡面定義了一個抽象函數(在傳回值前面加上abstract),裡面的函數沒有方法體,因為父類不知道每個子類需要實作什麼方法,是以子類隻需要建立一個和父類相同的函數方法,表示重寫父類的抽象方法,就可以自己來實作自己特有的函數方法體,而且子類必須都要重寫一遍抽象類(父類)的抽象方法****)

文法:

abstract

public abstract class Application {
public abstract test();//沒有方法體
}
           

接口:

聲明類的關鍵字是class,聲明接口的關鍵字是interface

接口連構造方法都沒有,自然沒法被執行個體化

普通類:隻有具體的實作

抽象類:具體實作和規範(抽象方法)都有

接口:隻有規範!自己無法寫方法,專業的限制,限制和實作分離

  • 接口就是規範,定義得是一組規則,展現了現實世界“如果你是…則必須能…”的思想,如果你是天使,則必須能飛,如果你是汽車,則必須能跑,如果你是好人,則必須幹掉壞人,如果你是壞人,則必須欺負好人
  • 接口的本質是契約,就像我們人間的法律一樣,制定好後,大家都遵守
  • OO的精髓,是對對象的抽象,最能展現這一點的就是接口

文法:

interface 定義接口的關鍵字,代替class

implements 類繼承接口的關鍵字

示例:

UserService接口:

//interface 定義的關鍵字
public interface UserService {
    //接口中的所有定義其實都是抽象的 public abstract
     void run(String name);//可以不寫public
     void delete(String name);
     void update(String name);
}
           

Teacher接口:

public interface Teacher {
    void teach();
    void classBegin();
}
           

UserServiceImp繼承接口的類:

  • 類可以實作接口, implements 實作接口
  • 實作了接口的類,就需要重寫接口的方法
  • 接口可以實作多繼承
//類可以實作接口, implements 實作接口
//實作了接口的類,就需要重寫接口的方法
//接口可以實作多繼承
public class UserServiceImp implements UserService,Teacher {
    //UserService接口的抽象接方法,子類重寫接口的抽象方法
    @Override
    public void run(String name) {
        System.out.println("我是運作");
    }
    @Override
    public void delete(String name) {
        System.out.println("我是删除");
    }
    @Override
    public void update(String name) {
        System.out.println("我是更新");
    }
    //Teacher接口的抽象方法,子類重寫接口的抽象方法
    @Override
    public void teach() {
        System.out.println("我是教學");
    }
    @Override
    public void classBegin() {
        System.out.println("我是上課");
    }
}
           

内部類:

  • 在一個類的内部在定義一個類就是内部類,對于内部類來說,外面的類就是外部類
  • 内部類可以實作外部類的私有屬性

用法:

要使用内部類,先要執行個體化外部類的對象,然後通過對象來執行個體化内部類

執行個體化外部類:

Student t = new Student();
           

執行個體化内部類:

Student t = new Student();
t.hand hand= t.new hand();//執行個體化内部類