java面向?qū)ο?---基礎進階01

1.類:一個Java代碼中可以定義多個類,但是只有一個類是用public修飾的,而且public修飾的類名必須成為代碼文件的名稱。
2.定義類的格式:

修飾符 class 類名{

成員變量:描述類和對象的屬性信息。

成員方法:描述類或?qū)ο蟮男袨樾畔⒌摹?/p>

構(gòu)造器:初始化一個類對象并返回引用。

代碼塊:

內(nèi)部類:

}

3.構(gòu)造器的格式:

修飾符 類名(形參){

}

4.構(gòu)造器初始化對象的格式:

類名 對象名稱=new 構(gòu)造器;

一個類默認有一個無參構(gòu)造器,不寫也存在,但是寫了之后會覆蓋無參構(gòu)造器。

5.this關鍵字

this代表當前對象的引用。

this可以用在實例方法和構(gòu)造器中。

this用在方法中,誰調(diào)用這個方法,this就代表誰。

this用在構(gòu)造器,代表構(gòu)造器正在初始化那個對象的引用。

一、java的三大特征(封裝、繼承、多態(tài))

1.封裝
作用:1.可以提高安全性。
2.可以實現(xiàn)代碼的組件化。
規(guī)范/要求:
1.建議成員變量都私有,使用prvate修飾的方法,成員變量,構(gòu)造器只能在本類使用。
2.提供成套的getter/setter方法暴露成員變量的取值和賦值,public修飾符,是公開的意義。
小結(jié):
封裝的核心思想:合理隱藏,合理暴露。
封裝已經(jīng)成為Java代碼的風格,即使代碼毫無意義,還是要按照封裝的規(guī)范寫代碼。
成員變量私有,提供getter+setter方法。
static關鍵字:我們定義了很多的成員變量,比如(name,age,sex)我們只寫了一份,但是發(fā)現(xiàn)很多的對象都可以使用,就說明java中這些成員變量或者方法是存在所屬性的,有些是屬于對象的,有些是屬于類本身的。
java是成員變量是否具有static關鍵字修飾來區(qū)分是屬于類的還是屬于對象的。

成員變量

1.靜態(tài)成員變量(類變量)
有static修飾的,屬于類本身的,與類一起加載一次,使用類名直接訪問即可。
類名.靜態(tài)成員變量
對象.靜態(tài)成員變量
2.實例成員變量
對象.實例成員變量
屬于類的每個對象的,與類的對象一起加載,對象有多少個就加載多少次。

成員方法

1.靜態(tài)方法
有static修飾的成員方法叫靜態(tài)方法也叫類方法,屬于類本身,使用類名直接訪問即可。
2.實例方法
無static修飾的成員方法叫實例方法,屬于類每個對象的,必須使用類的對象來訪問。
package com.itppf.成員變量的訪問;

public class Student {
    public static String name="李四";
    public String sex;


    public static void main(String[] args) {
        //注意,靜態(tài)變量可以使用類名或者對象名來調(diào)用
        System.out.println(Student.name);
        //在同一個類中,省略類名
        System.out.println(name);
        //如果使用對象名
        Student student=new Student();
        student.name="張三";
        student.sex="男";
        System.out.println(student.name);


        //注意,實例變量不能使用類名來調(diào)用
//        System.out.println(Student.sex);
       //實例變量但是可以使用對象來調(diào)用
        System.out.println(student.sex);
    }
}

注:在同一個類當中,可以直接使用類名.方法來調(diào)用實例方法。但是不推薦,可以創(chuàng)建對象來調(diào)用。


2.繼承
繼承的優(yōu)勢就是把相同的代碼寫在父類中,提高代碼的復用性。
簡單案例一:教務系統(tǒng)
角色一:老師(姓名,年齡,性別,身高,活動,教課)。
角色二:學生(姓名,年齡,性別,身高,學習,成績)。
角色三:管理員(姓名,年齡,性別,身高,操作)。
package com.itppf.繼承;

public class Person {
    private String name;
    private String sex;
    private int age;
    private double height;
    private double weight;

    public void setName(String name){
        this.name=name;
    }
    public String getName(){
        return this.name;
    }

    public void setSex(String sex){
        this.sex=sex;
    }
    public String getSex(){
        return this.sex;
    }

    public void setAge(int age){
        this.age=age;
    }
    public int getAge(){
        return this.age;

    }

    public void setHeight(double height){
        this.height=height;
    }
    public double getHeight(){
        return this.height;
    }

    public void setWeight(double weight){
        this.weight=weight;
    }
    public double getWeight(){
        return this.weight;
    }

}
package com.itppf.繼承;

public class Student extends Person {
    public void action(){
        System.out.println(this.getName()+"學生學習");
    }
}
package com.itppf.繼承;

public class Teacher extends Person{
    public void teach(){
        System.out.println(this.getName()+"老師教課");
    }
}
package com.itppf.繼承;

public class Administrator extends Person{
public void option(){
    System.out.println(this.getName()+"進行操作");
}
}
package com.itppf.繼承;

public class Test {
    public static void main(String[] args) {
        Person p1=new Student();
        Person p2=new Teacher();
        Person p3=new Administrator();

        p1.setName("學生1");
        p1.setAge(12);
        p1.setHeight(180.0);
        p1.setWeight(140.00);
        System.out.println("學生姓名:"+p1.getName());
        System.out.println("學生年齡:"+p1.getAge());
        System.out.println("學生身高:"+p1.getHeight());
        System.out.println("學生體重:"+p1.getWeight());
        ((Student) p1).action();
        System.out.println("****************");
        p2.setName("老師1");
        p2.setAge(12);
        p2.setHeight(180.0);
        p2.setWeight(140.00);
        System.out.println("老師姓名:"+p2.getName());
        System.out.println("老師年齡:"+p2.getAge());
        System.out.println("老師身高:"+p2.getHeight());
        System.out.println("老師體重:"+p2.getWeight());
        ((Teacher) p2).teach();
        System.out.println("****************");
        p3.setName("管理員1");
        p3.setAge(12);
        p3.setHeight(180.0);
        p3.setWeight(140.00);
        System.out.println("管理員姓名:"+p3.getName());
        System.out.println("管理員年齡:"+p3.getAge());
        System.out.println("管理員身高:"+p3.getHeight());
        System.out.println("管理員體重:"+p3.getWeight());
        ((Administrator) p3).option();
        System.out.println("****************");

    }
}
繼承不了東西:
1.構(gòu)造器繼承不了,構(gòu)造器父類是初始化自己的(子類可以使用,但是這里不是繼承而是共享)。
有爭議的觀點:
1.父類的私有成員變量和方法。
2.父類的靜態(tài)成員變量。
package com.itppf.子類無法繼承;

public class Animal {
    public  String name;
    public void eat(){
        System.out.println("動物可以吃東西!");
    }
}
//創(chuàng)建子類
package com.itppf.子類無法繼承;

public class Cat extends Animal{
}
//創(chuàng)建測試類,程序入口
package com.itppf.子類無法繼承;

public class Test {
    public static void main(String[] args) {
        Animal animal=new Cat();
        animal.eat();
    }
}

解釋1:以上這些代碼這樣是完全可以的,但是是private呢?



那么有什么辦法可以讓它繼承呢?

可以的,可以有私有成員變量,只是不能直接獲取。反射技術(shù),暴力破解。

解釋2:靜態(tài)變量和方法可以繼承,但是這個屬于共享,不屬于繼承。因為這個東西是父類獨有的,只有一份。

繼承后成員變量的特點:

就近原則:子類繼承父類以后,子類定義變量和父類重名,調(diào)用的時候先調(diào)子類的成員變量,要是子類沒有或者不重名,則調(diào)用父類?;蛘呖梢允褂胻his.xxx和super.xxx來區(qū)分。

繼承后子類方法的特點:

就近原則:子類繼承父類以后,調(diào)用方法的時候還是先調(diào)子類,后調(diào)父類,方法一樣,優(yōu)先使用子類已有的方法。

方法的重寫

子類繼承了父類,子類就得到了父類的某個方法。但是子類覺得這個方法不好或者無法滿足自己的需求,子類就重寫一個與父類聲明一樣的方法來覆蓋父類的該方法,于是就進行方法的重寫。

方法重寫的校驗注解 @Override

因為方法的重寫的時候,如果方法名稱寫錯,會調(diào)用父類的方法,引入@Override了之后,則不會有這種問題,可讀性好,安全。

1.子類重寫方法的形參列表與名稱必須和父類一致。

2.子類重寫方法的返回值類型聲明要么和父類一致,要么比父類方法返回值類型范圍更小。

3.子類重寫方法的修飾符權(quán)限應該與父類被重寫方法的修飾符權(quán)限相同或者更大。

總結(jié):1.加注解

? 2.聲明不變,重新實現(xiàn)。

super訪問父類方法

方法重寫之后,還需要調(diào)用父類的方法,因此需要使用super,進行父類引用。



這樣是不能直接調(diào)用,只可以在子類的方法中進行調(diào)用,使用實例方法調(diào)用實例方法的特點,就是做一個中轉(zhuǎn)。

package com.itppf.super關鍵字;

public class Animal {
    public void eat(){
        System.out.println("父類方法!");
    }

}
package com.itppf.super關鍵字;

public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("子類重寫方法!");
    }
    public void go(){
        super.eat();
    }
}
package com.itppf.super關鍵字;

public class Test {
    public static void main(String[] args) {
//       Animal animal=new Cat();
//        Cat cat=(Cat)animal;
//        cat.go();

        Cat cat=new Cat();
        cat.go();
        cat.eat();//重寫過了
    }
}
注:注掉的是使用多態(tài)進行強轉(zhuǎn),父類強轉(zhuǎn)為子類,向下轉(zhuǎn)型,進行調(diào)用,eat()方法也可以是因為eat()被重寫過了,這里的go方法相當于一個中轉(zhuǎn)。
方法重寫的拓展

1.私有方法可以被重寫嗎?不可以

繼承后的構(gòu)造器的特點

子類構(gòu)造器的第一行首先是默認訪問父類的無參構(gòu)造器再訪問自己的構(gòu)造器,主要有個默認的super()方法。

package com.itppf.構(gòu)造器;

public class Father {
    public Father(){ 
    super();        //調(diào)用父類的構(gòu)造方法
        System.out.println("父類的構(gòu)造器!");
    }
}
package com.itppf.構(gòu)造器;

public class Son extends Father{
    public Son(){
    //這里默認有個super();
        System.out.println("子類的構(gòu)造器");
    }
}
package com.itppf.構(gòu)造器;
public class Test {
    public static void main(String[] args) {
        Son son=new Son();
    }
}

注:這里有一個重要的問題,子類構(gòu)造器和父類構(gòu)造器的問題。

作用:可以給父類構(gòu)造方法傳遞實參,給父類中的字段賦值。 因為子類中創(chuàng)建該類的對象,可以給子類構(gòu)造方法傳遞參數(shù),在子類構(gòu)造方法中調(diào)用父類帶參數(shù)構(gòu)造方法,可以給父類構(gòu)造方法傳參數(shù),父類中對應帶參數(shù)的構(gòu)造方法,可以給內(nèi)部的字段或方法傳參數(shù)值。

為什么在新建子類時要先調(diào)用父類的構(gòu)造器?

子類構(gòu)造器會默認調(diào)用 父類的無參構(gòu)造器,如果父類沒有無參構(gòu)造器,則需在子類構(gòu)造器的第一行顯式地調(diào)用父類的其他構(gòu)造器。

其次,從繼承的思想來看,你繼承一個類,就相當于擴展一個類,形成一個更為特殊的類,但經(jīng)常,我們需要將子類向上轉(zhuǎn)型為基類,以便使用或達到其他各種目的。

這時,如果你生成子類對象時沒有調(diào)用父類的構(gòu)造器,那么,我們在使用父類的一些成員變量的時候,就會報變量未初始化的錯誤。請記住,變量初始化總是在構(gòu)造器調(diào)用之前完成!

構(gòu)造一個對象,先調(diào)用其構(gòu)造方法,來初始化其成員函數(shù)和成員變量。子類擁有父的成員變量和成員方法,如果不調(diào)用,則從父類繼承而來的成員變量和成員方法得不到正確的初始化。

舉個例子:Animal(父類)
package com.itppf.構(gòu)造器;

public class Animal {
    private String name;
    private String sex;
    private int age;
    public  Animal(){

 }
    public Animal(String name,String sex,int age){
        this.name=name;
        this.sex=sex;
        this.age=age;
    }

    public  void  setName(String name){
        this.name=name;
    }
    public String getName(){
        return this.name;
    }
    public void  setSex(String sex){
        this.sex=sex;
    }
    public String getSex(){
        return this.sex;
    }
    public void setAge(int age){
        this.age=age;
    }
    public  int getAge(){
        return this.age;
    }

}

Cow類:

package com.itppf.構(gòu)造器;

public class Cow extends Animal{
    public Cow(String name,String sex,int age){
      super(name,sex,age);  //根據(jù)參數(shù)匹配調(diào)用父類構(gòu)造器,這里選擇調(diào)用有參數(shù)的構(gòu)造器,因為super()傳參了。
    }
     public void eat(){
         System.out.println(getName()+"吃草");
     }
}

測試類:

package com.itppf.構(gòu)造器;

public class Test2 {
    public static void main(String[] args) {
        Cow cow=new Cow("奶牛","雌",12);
    }
}

1.這里是 Cow cow=new Cow("奶牛","雌",12);---------------->

2.傳遞給Cow有參構(gòu)造器進行初始化public Cow(String name,String sex,int age){...}而這里會默認調(diào)用父類的無參構(gòu)造器,因為省略了super(),所以定義需要定義父類的無參構(gòu)造器,其實不用調(diào)用也行,因為我們傳遞的是有參的構(gòu)造器,但是為了規(guī)范還是新建了無參構(gòu)造器。super(name,sex,age)---------------------->

3.將數(shù)據(jù)傳遞給父類的有參構(gòu)造器。---------------------->

4.父類構(gòu)造器使用this.name=name;賦值給this.name;

this關鍵字和super關鍵字

調(diào)用兄弟構(gòu)造器,以上面的例子為例,假如我不想傳遞三個構(gòu)造方法,只想讓年齡這個參數(shù)默認為12。

那么我就要新建一個只含兩個參數(shù)的兄弟構(gòu)造器.

package com.itppf.this和super;

public class Animal {
    private String name;
    private  String sex;
    private  int age;

    public Animal(){

    }
    //鼠標左鍵+ctrl自動跳躍到下面構(gòu)造器,這里傳進來兩個值,age默認為18
    public Animal(String name,String sex){
        this(name,sex,16);
    }
    public Animal(String name,String sex,int age){
        this.name=name;
        this.sex=sex;
        this.age=age;
    }

    public void setName(String name){
        this.name=name;
    }
    public String getName(){
        return this.name;
    }
    public void setSex(String sex){
        this.sex=sex;
    }
    public String getSex(){
        return this.sex;
    }
    public void setAge(int age){
        this.age=age;
    }
    public int getAge(){
        return this.age;
    }
}
package com.itppf.this和super;

public class Test {
    public static void main(String[] args) {
        //給構(gòu)造方法傳值
        Animal animal1=new Animal("小狗","雄",18);
        System.out.println(animal1.getName());
        System.out.println(animal1.getSex());
        System.out.println(animal1.getAge());
        System.out.println("*******************");
        //給構(gòu)造器傳兩個值,讓構(gòu)造器調(diào)用兄弟構(gòu)造器
        Animal animal2=new Animal("小貓","雌");
        System.out.println(animal2.getName());
        System.out.println(animal2.getSex());
        System.out.println(animal2.getAge());
    }
}
這里突然產(chǎn)生了一個問題,使用set傳值和構(gòu)造器傳值有什么不同?

答:其實就是構(gòu)造方法傳值只是初始化,而使用set方法則是修改屬性值。

  • this(...)借用本類構(gòu)造器。
  • super(...)借用父類構(gòu)造器。
  • this(...)和super(...)必須放在構(gòu)造器的第一行,否則報錯。
  • 所以this(...)和super(...)不能同時出現(xiàn)在構(gòu)造器中。
繼承的特點:
1.單繼承:一個類只能繼承一個直接父類。
2.多層繼承:一個類可以間接繼承多個父類。
為什么java是單繼承?

設計層面的東西可以使用反證法。

3.一個類可以有多個子類
5.一個類默認繼承了Object類,要么間接繼承了Object類,Object是java的基類。

引用類型作為方法參數(shù)和返回值(對象的回調(diào))

package com.itppf.對象的回調(diào);

public class Cat {
    public void type(){
        System.out.println("你覺得它是什么品種的貓?");
    }
}
package com.itppf.對象的回調(diào);
public class Test {
    public static void main(String[] args) {
        Cat fatcat=new Cat();
        answer(fatcat);
    }
    public static void answer(Cat cat){
        cat.type();
        System.out.println("這個品種的貓怎么樣?");
    }
}

傳遞流程:new Cat()創(chuàng)建的地址存儲在fatcat里面--------->fatcat會傳到answer(fatcat);里面---------------->然后再傳給answer(Cat cat)里面的cat。---------------->最后調(diào)用answer方法里面的type()方法。

引用類型作為成員變量

package com.itppf.引用類型作為成員變量;

public class Student {
    private String name;
    private String sex;
    private int age;
    private Address address;   //引用類型的變量
    //無參構(gòu)造器
    public Student(){

    }
    //有參構(gòu)造器,不過這里使用的是set方法傳值
//    public Student(String name,String sex,int age){
//        this.name=name;
//        this.sex=sex;
//        this.age=age;
//    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
package com.itppf.引用類型作為成員變量;

public class Address {
    private String name;
    private String code;
    private double x;
    private double y;
    //無參構(gòu)造器
    public Address(){

    }
    //有參構(gòu)造器
    public Address(String name,String code,double x,double y){
        this.name=name;
        this.code=code;
        this.x=x;
        this.y=y;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }
}
package com.itppf.引用類型作為成員變量;

public class Test {
    public static void main(String[] args) {
        Student s1=new Student();
        s1.setName("張三");
        s1.setSex("男");
        s1.setAge(12);
        System.out.println("姓名:"+s1.getName()+"\t性別:"+s1.getSex()+"\t年齡:"+s1.getAge());

        //這里使用構(gòu)造器傳遞初始值
        Address address=new Address("北京","02020",150.0,120.0);
        //這里將剛剛new的地址實例傳入到s1實例的地址信息中。
        s1.setAddress(address);
        //這里創(chuàng)建了一個地址實例,用來調(diào)用引用型變量Address的屬性值。
        Address address1=s1.getAddress();
        System.out.println(address1.getName()+"\t"+address1.getCode()+"\t"+address1.getX()+"\t"+address1.getY());
    }
}

總結(jié):以上就是我所學java進階的第一階段,這個階段主要是對前面內(nèi)容進行了一個深度的總結(jié)和升。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容