1. 程式人生 > 其它 >java基礎學習筆記 - 面向物件課時1

java基礎學習筆記 - 面向物件課時1

p67 封裝詳解

1、封裝的好處:
1)程式設計要追求“高內聚 低耦合”,高內聚就是類的內部資料操作細節自己完成,不許外部干涉;低耦合即僅暴露少量的方法給外部使用
2)複雜性封裝,只對外提供簡單的操作入口, 隱藏程式碼的實現細節,看不到實物複雜的那一面,只展示事物簡單的一面
3)封裝之後形成真正的“物件”,真正的“獨立體”,增強了系統的可維護性
4)封裝之後提高了程式碼的安全性,保護了資料
5)封裝意味著有統一介面,程式可以重複使用,適應性強

2、封裝的實現:屬性私有-get/set
1)類的所有屬性私有化,外部程式不能直接訪問,使用private關鍵字修飾,private修飾的資料只能在當前類中訪問
2)對外提供簡單的操作入口,以後外部程式想要方問物件,必須通過這些簡單的入口進行訪問:
  - 對外提供兩個公開的方法作為入口,get/set方法
  -set/get方法必須是 public修飾的


  - 呼叫set方法修改屬性,set方法只負責修改資料,沒有返回值,通過傳參修改例項變數的值
  - 呼叫get方法讀取屬性,有返回值型別,get方法負責返回該型別的資料
  - 可以在get/set的方法體中進行安全過濾

3、get/set 的語法:

    public 返回值型別 getName(){return field;}
    public void setName(形參){ }

    public returntype getName(){
      return field;  }

    public void setName(type variable){
      this.field = value;


      ... ...   }

//示例3-1

public class D03{
    public static void main(String[] args){
        
        Student s = new Student();
        
        //通過方法傳參設定值
        s.setName("小明",13,'男');
        
        //列印返回的資料
        System.out.println(s.getName());
        System.out.println(s.getAge());
        System.out.println(s.getSex());
        
    }
}


//Student類 public class Student{ //屬性私有 private String name; private int age; private char sex; //提供一些可以操作類的屬性的方法 //提供一些 public的 get、set方法 //給資料設定值 public void setName(String name,int age,char sex){ this.name = name; this.age = age; this.sex = sex; } //獲取這個資料 public String getName(){ return this.name; } public int getAge(){ return this.age; } public char getSex(){ return this.sex; } }
View Code

//示例3-2:構造器測試,過載,get/set測試

//構造器類
public class Constructor{
    
    public static void main(String[] args){
        
        //呼叫無參構造
        Account act1 = new Account();
        
        //通過入口訪問物件的屬性
        System.out.println("賬號:" + act1.getActno());
        System.out.println("餘額:" + act1.getBalance());
        
        //呼叫有參構造
        Account act2 = new Account("110",10000);
        
        //訪問物件的屬性
        System.out.println("賬號:" + act2.getActno());
        System.out.println("餘額:" + act2.getBalance());
        
        //通過入口修改物件的屬性
        act2.setActno("act-110");
        act2.setBalance(200000);
        System.out.println("賬號:" + act2.getActno());
        System.out.println("餘額:" + act2.getBalance());
    }
}


//定義賬戶類
public class Account{
    
    private String actno;
    private double actbalance;
    
    //構造方法過載
    //構造方法初始化例項變數手動或預設
    public Account(){
        //actno = null;
        //actbalance = 0.0;
    }
    
    public Account(String s){
        actno = s;
        //actbalance = 0.0;
    }
    
    public Account(double d){
        //actno = null;
        actbalance = d;
    }
    
    public Account(String s, double d){
        actno = s;
        actbalance = d;
    }
    
    //訪問入口get/set
    public String getActno(){
        return actno;
    }
    public void setActno(String actno){
        this.actno = actno;
    }
    
    public double getBalance(){
        return actbalance;
    }
    public void setBalance(double balance){
        this.actbalance = balance;
    }
}
View Code

p68 繼承 extends關鍵字
  - 繼承是類和類之間的一種關係,此外類和類之間的關係還有依賴、組合、聚合等
  - 繼承的本質是對一批類的抽象,從而實現對現實世界更好的建模
  - 繼承關係的兩個類,子類是派生類,父類的基類
  - 子類繼承父類,子類是父類的擴充套件,子類擁有父類的全部的屬性和方法
  - java中類只有單繼承沒有多繼承,一個子類只能繼承一個父類,一個父類可以擴充套件多個子類
  - java中所有的類都預設繼承 Object類

    public class 子類名 extends 父類名{ }

2、有 final 修飾的類將不能被繼承
如:pubic final class person{} //該類將不能被繼承

示例4:

public class D04{
    public static void main(String[] args){
        
        Student student = new Student();
        
        student.say();            //說了一句話
        System.out.println(student.money);    //10_0000_0000
    }
}


//Person類
public class Person{
    
    public int money = 10_0000_0000;
    
    public void say(){
        System.out.println("說了一句話");
    }
}


//Student類
public class Student extends Person{}
View Code

p70 重寫override

1、重寫與父類引用的邏輯
  -在繼承關係中,子類可以重寫父類的方法,屬性不存在重寫
  - 重寫的方法通常是非靜態的、public的
  - 父型別的引用可以指向子類物件,但子類的引用不能指向父類物件
  - 父型別的引用指向子類物件,相當於建立了一個新的隱藏的子型別的物件,但它沒有該子類的元素,而是隻繼承父類的所有屬性和方法,被重寫的方法在這裡被覆蓋,因此通過父類引用呼叫重寫的方法,相當於呼叫了子類的方法,父類引用也無法真正訪問子類物件
  - 如果重寫的方法是靜態的,父類的引用仍然呼叫父類的方法,靜態的方法無法被重寫

2、重寫的語法
  - 重寫的方法名、引數列表都必須相同
  - 重寫的方法體不同,執行的功能不同
  - 修飾符:範圍可以擴大但不能縮小 public>protected>default>private
  - 丟擲的異常:範圍可以被縮小但不能擴大 ClassNotFoundException < Exception
3、為什麼需要重寫
  - 父類的功能,子類不一定需要或者不一定滿足

4、以下情況不能重寫:
  - static 修飾的方法
  - private 修飾的方法
  - final 定義的常量

//示例7-1:重寫靜態方法的呼叫

public class T07{
    public static void main(String[] args){
        
        A a = new A();
        B b = new A();
        
        a.test();  //相當於A.test();
        b.test();  //相當於B.test();
    }
}


//子類重寫父類的方法
public class A extends B{
    public static void test(){
        System.out.println("A=>test()");
    }
}


//父類
public class B{
    public static void test(){
        System.out.println("B=>test()");
    }
}
View Code

//示例7-2:重寫非靜態方法的呼叫

public class T07{
    public static void main(String[] args){
        
        A a = new A();
        B b = new A();
        //非靜態方法的重寫,通過引用呼叫的方法是物件的方法
        a.test();  //A=>test()
        b.test();  //A=>test()
    }
}


//子類重寫
public class A extends B{
    public void test(){
        System.out.println("A=>test()");
    }
}


//父類
public class B{
    public void test(){
        System.out.println("B=>test()");
    }
}
View Code

//示例7-3:重寫的辯證 父類引用指向子類物件的情況

public class T07{
    public static void main(String[] args){
        //非靜態方法的重寫
        A a = new A();
        B b = new A();    //相當於隱藏建立了一個父類物件
        
        //重寫方法時,父類的引用預設呼叫子類的方法
        a.test();  //A=>test()
        b.test();  //A=>test()
        
        //顯示建立父類物件,呼叫被重寫的父類方法
        B c = new B();
        c.test();  //b=>test()
        
        //不能呼叫子類獨有的方法
        //b.test1();
        
        //可以訪問父類的屬性 、方法
        System.out.println(b.name);        
        b.test2();
    }
}


//子類繼承父類
public class A extends B{
    
    //重寫方法
    public void test(){
        System.out.println("A=>test()");
    }
    
    //獨有方法
    public void test1(){
        System.out.println("A1=>test()");
    }
}


//父類
public class B{
    
    String name;
    
    public void test(){
        System.out.println("B=>test()");
    }
    
    public void test2(){
        System.out.println("B2=>test()");
    }
}
View Code

p71 多型:
  - 多型是方法的現象,屬性沒有多型性
  - 多型存在於有繼承關係的類中,父類引用指向子類物件
  - 一個物件的實際型別是確定的,但指向它的引用的型別可以有多個父類型別
  - 子類能呼叫的方法都是它自己的或者繼承父類的
  - 父型別的引用可以指向子類物件,但是不能呼叫子類獨有的屬性和方法,只能呼叫子類重寫的方法
  - 用強制轉換型別的辦法,使父類引用s2的型別降級,就可以得到一個指向子類物件的子類引用,這時該引用可以完全訪問子類物件

例:Student s1 = new Student();
  Person s2 = new Student();
  Object s3 = new Student();
  ((Student)s2).eat();

//示例8:

//測試類
public class T08{
    public static void main(String[] args){
        
        //指向物件的引用型別是多種的
        Student s1 = new Student();
        Person s2 = new Student();
        Object s3 = new Student();
        
        s1.run();    //Student run
    
        //子類重寫了父類run()方法,S2預設呼叫子類的方法
        s2.run();    //Student run
        
        //s2不能呼叫子類獨有的方法
        //s2.eat();
        
        //用強制轉換型別的辦法,使s2型別降級,可以訪問子類物件,可能會丟失什麼
        ((Student)s2).eat();
    }
}


//子類
public class Student extends Person{
    
    //重寫run()方法
    public void run(){
        System.out.println("Student run");
    }
    
    //子類的獨有方法
    public void eat(){
        System.out.println("Student eat");
    }
}


//父類
public class Person{
    
    public void run(){
        System.out.println("Person run");
    }
}
View Code

//即使再小的帆也能遠航2021-11-13