Java基礎(二)面向對象(上)


面向對象基礎知識

面向對象是相對面向過程而言的 面向對象和面向過程都是一種思想 面向過程強調的是功能行為 面向對象將功能封裝進對象,強調具備了功能的對象 面向對象是基於面向過程的

面向對象的特征:

  • 封裝
  • 繼承
  • 多態

java中用類Class來描述事物: 屬性:對應類中的成員變量 行為:對應類中的成員函數

成員變量 成員變量定義在類中,在整個類中都可以被訪問 成員變量隨着對象的建立而建立,存在於對象所在的堆內存中 成員變量有默認初始化值

局部變量 局部變量之定義在局部范圍內,如函數內 局部變量存在棧內存中 作用的范圍結束,變量空間會自動釋放 局部變量沒有默認初始化值

匿名對象 匿名對象是對象的簡化形式 匿名對象有兩種使用情況: 當對象方法僅進行一次調用時 匿名對象可以作為實際參數進行傳遞

heap-stack

java -x 輸出java的非標准選項 java -Xss<size> xxx 設置stack大小 如:java -Xss521k

java -Xmx 設置堆最大值 java -Xms 設置堆初始值

java中對象和數組都位於堆內存中,局部變量函數參數等都位於棧內存中

封裝

封裝是指隱藏對象的屬性和實現細節,僅對外提供公共訪問方式

封裝原則: 將不需要對外提供的內容都隱藏起來 把屬性都隱藏起來,提供公共方法對其訪問

代碼例子:

package study_java.ex01;

public class ClassDemo1 {
    public static void main(String[] args){
        Man man = new Man();
        // 不能直接通過man訪問到money,只能通過getMoney方法
        System.out.println(man.getMoney());
        man.addMoney(100);
        System.out.println(man.getMoney());
        // 對於public的變量我們可以直接通過man訪問
        System.out.println(man.age);
    }

}

class Man{
    private int money = 100;
    public int age = 23;

    // 通過封裝的方式獲取money
    public int getMoney(){
        return money;
    }
    // 通過封裝的方式修改money
    public void addMoney(int num){
        money += num;
    }
}

private關鍵字

是一個權限修飾符 用於修飾成員變量和成員函數 被私有化的成員只在本類中有效

常用於: 將成員變量私有化,對外提供對應的set,get方法對其進行訪問,提高對數據訪問的安全性

構造函數

函數名與類名相同 不用定義返回值類型 沒有具體的返回值

作用:給對象進行初始化

package study_java.ex01;

public class ConstructDemo1 {

    public static void main(String[] args){
        Dog d = new Dog("aa");
        d.watch();
    }
}

class Dog{
    private String name;
    private String color;

    // 構造函數
    public Dog(String n){
        name = n;
        System.out.println("new Dog()");
    }

    public void watch(){
        System.out.println("旺旺");
        System.out.println(name);
    }

}

構造代碼塊也是類成員,是為構造函數添加共有的一些內容 並且構造函數先於構造函數執行

對象的創建過程: 當new一個對象的時候

  • 在內個存中分配內存空間
  • 對成員變量賦默認值
  • 執行構造代碼塊或賦值語句,執行順序從上到下執行
  • 構造函數

靜態代碼塊

使用static修飾的代碼構造塊,在類加載的時候調用一次,以后不再調用。 通常放置對靜態成員的初始化過程

static成員,跟對象無關,訪問的方式是通過Class.XXX()

this關鍵字

this:代表其所在函數所屬對象的引用,即this代表類對象的引用

static 關鍵字

用於修飾成員(成員變量和成員函數)

被修飾后的成員具備以下特點: 隨着類的加載而加載 優先於對象存在 被所有的對象所共享 可以直接被類名調用

使用注意: 靜態方法只能訪問靜態成員 靜態方法不能寫this,super關鍵字 主函數是靜態的

代碼例子如下:

package study_java.ex01;

public class StaticDemo1 {
    public static void main(String[] args){
        System.out.println(Benz.brand1);

        Benz b1 = new Benz();
        System.out.println(b1.getBrand());

        // 直接訪問靜態方法
        System.out.println(Benz.getBrand1());
    }
}

class Benz{
    // 靜態成員
    private static String brand = "BENZ";

    public static  String brand1 = "BENZ1";

    private String color;

    public void setColor(String color){
        this.color = color;
    }

    public String getBrand(){
        return brand;
    }

    public static String getBrand1(){
        return brand;
    }
}

this(): 調用其他構造函數的方式,而且必須作為第一條語句

繼承

多個類中存在相同的屬性和行為時,將這些內容抽取到單獨一個類中,那么多個類無需再定義這些屬性和行為,只要繼承那個類即可。

多個類可以稱為子類,單獨這個類稱為父類 子類可以直接訪問父類中國非私有的屬性和方法 通過extends關鍵字讓類與類之間產生繼承 java中只支持單沖繼承 + 多層繼承

簡單的例子:

package study_java.ex01;

public class ExtendsDemo1 {

    public static void main(String[] args){
        JingBa jingba = new JingBa();
        jingba.name = "大黃";
        jingba.watch();
        jingba.owner="zz";
    }


}


class Animal{
    public String name;
    public int weight;
    public void move(){
        System.out.println("move.....");
    }
}

class Dog extends Animal{
    public void watch(){
        System.out.println("有人來了");
    }
}

class JingBa extends Dog{
    public String owner;
}

super關鍵字

調用的是父類的構造函數,必須是第一條語句 通過下面例子理解:

package study_java.ex01;

public class ExtendsDemo2 {

    public static void main(String[] args){
        // 創建對象
        BMWSportCar mychar = new BMWSportCar();
        mychar.color = "red";
        mychar.velocity = 200;
        mychar.price = 20000;
        mychar.run();

    }
}

class Car{
    public String color;
    public void run(){
        System.out.println("running.....");
    }

    public Car(String color){
        this.color = color;
        System.out.println("new car("+color+")");
    }
}

class SportCar extends Car{
    public int velocity;
    public SportCar(int velocity){
        super("yellow");
        this.velocity = velocity;
        System.out.println("new SportCar("+velocity +")");
    }
}

class BMWSportCar extends SportCar{
    public int price;

    public BMWSportCar(){
        super(200);
        System.out.println("new BMWSportCar");
    }
}

如果被繼承的父類的屬性是私有的,如果想要訪問或者更改,可以通過定義公有的方法來實現,代碼例子如下:

package study_java.ex01;

public class ExtendsDemo2 {

    public static void main(String[] args){
        // 創建對象
        BMWSportCar mychar = new BMWSportCar();
        mychar.setColor("red");
        mychar.velocity = 200;
        mychar.price = 20000;
        mychar.run();
        System.out.println(mychar.getColor());

    }
}

class Car{
    //私有屬性
    private String color;
    public void run(){
        System.out.println("running.....");
    }

    public Car(){

        System.out.println("new car()");
    }
    // 公有方法
    public String getColor(){
        return color;
    }
    public void setColor(String color){
        this.color = color;
    }
}

class SportCar extends Car{
    public int velocity;
    public SportCar(){
        System.out.println("new SportCar()");
    }
}

class BMWSportCar extends SportCar{
    public int price;

    public BMWSportCar(){
        System.out.println("new BMWSportCar");
    }
}

super和this的用法有點相似

  • this代表本類對象的引用
  • super代表父類的內存空間的標識
  • 子類要調用父類構造函數時,可以使用super()語句
  • 當子類和父類出現同名成員時,可以用super進行區分

super()和this()

調用父類的構造函數,必須是第一條語句

package study_java.ex01;

public class ExtendsDemo2 {

    public static void main(String[] args){
        // 創建對象
        BMWSportCar mychar = new BMWSportCar();
        mychar.setColor("red");
        mychar.velocity = 200;
        mychar.price = 20000;
        mychar.run();
        System.out.println(mychar.getColor());

    }
}

class Car{
    //私有屬性
    private String color;
    public void run(){
        System.out.println("running.....");
    }

    public Car(){

        System.out.println("new car()");
    }
    // 公有方法
    public String getColor(){
        return color;
    }
    public void setColor(String color){
        this.color = color;
    }
}

class SportCar extends Car{
    public int velocity;
    public SportCar(){
        System.out.println("new SportCar()");
    }
    public void setColorPro(String color){
        // this.color = color;  //這里和下面的的super是一樣的
        super.setColor(color);
    }

    public void setColor(String color){
        super.setColor(color);
    }

}

class BMWSportCar extends SportCar{
    public int price;

    public BMWSportCar(){
        System.out.println("new BMWSportCar");
    }
}

任何一個對象的創建都包含整個家族簇的創建,任何一個成員的創建,都包含這一整個順序的完成 通過下面代碼理解這個過程

package study_java.ex01;

public class ExtendsDemo3 {
    public static void main(String[] args){
        // 創建對象
        BMWSportCar mychar = new BMWSportCar();
        mychar.setColor("red");
        mychar.velocity = 200;
        mychar.price = 20000;
        mychar.run();
        System.out.println(mychar.getColor());

    }
}

class Car{
    //私有屬性
    private String color;

    {
        System.out.println("Cons Block in Car");
    }

    public void run(){
        System.out.println("running.....");
    }

    public Car(){

        System.out.println("new car()");
    }
    // 公有方法
    public String getColor(){
        return color;
    }
    public void setColor(String color){
        this.color = color;
    }
}

class SportCar extends Car{
    public int velocity;

    {
        System.out.println("Cons Block in SportCar");
    }
    public SportCar(){
        System.out.println("new SportCar()");
    }
    public void setColor(String color){
        super.setColor(color);
    }

}

class BMWSportCar extends SportCar{
    public int price;

    public BMWSportCar(){
        System.out.println("new BMWSportCar");
    }
}

函數覆蓋

子類中出現與父類中一模一樣的方法時,會出現覆蓋操作,也稱為重寫或者復寫 父類中的私有方法不可以被覆蓋 在子類覆蓋方法中,繼續使用被覆蓋的方法可以通過super函數名獲取

覆蓋時需要注意的問題: 覆蓋時,子類方法權限一定要大於等於父類方法權限 靜態只能覆蓋靜態

主要的應用是: 當子類需要父類的功能,而功能主題子類有自己特有的內容時,可以復寫父類中的方法,這樣就既沿襲了父類 的功能,又定義了父類特有的內容

代碼例子:

package study_java.ex01;

public class OverrideDemo1 {
    public static void main(String[] args){
        Rich2Man s2 = new Rich2Man();
        s2.consume(200000);
    }
}

class RichMan{
    public void consume(int money){
        if(money < 500){
            System.out.println("消費了"+money+"w");
        }
        else {
            System.out.println("不能消費了");
        }

    }
}

class Rich2Man extends RichMan{
    public void consume(int money){
        if(money < 50000){
            System.out.println("消費了"+money+"w");
        }
        else {
            System.out.println("不能消費了");
        }

    }
}

子類的實例化過程

子類中所有的構造函數morning都會訪問父類中空參數的構造函數 因為每一個構造函數的第一行都有一條默認的語句super() 子類會具備父類中的數據,所以要先明確父類是如何對這些數據初始化的。 當父類中沒有空參數的構造函數時,子類的構造函數必須通過this或者super語句指定要訪問的構造函數

final 關鍵字

final 可以修飾類,方法和變量

final 修飾的類不可以被繼承

final 修飾的方法不可以被覆蓋(可以繼承)

final 修飾的變量是一個常量只能被賦值一次

內部類只能訪問被final修飾的局部變量

 

package study_java.ex01;

public class FinalDemo1 {
    public static void main(String[] args){
        Jing8 j = new Jing8();
        j.watch();
        System.out.println(j.name);
    }
}

class Dog1{
    // 常量
    public final String name = "aaa";
    
    // final 修飾的方法不能重寫
    public /*final */ void watch(){
        System.out.println("來人了");
    }
}

class Jing8 extends Dog1{
    public void watch() {
        System.out.println("聽一聽");
        super.watch();
    }
}

關於內部類 定義在class內部的類 編譯產生OuterClass$Innerc.class 內部類訪問外部類的局部變量,需要final修飾

代碼例子:

package study_java.ex01;

public class InnerClassDemo {
    public static void main(String[] args){
        Car2 c = new Car2();
        c.run();
    }
}

class Car2{
    public String color = "red";
    public int tires;

    public void run(){
        new Engine().fire();
        System.out.println("running.....");
    }

    class Engine{
        public void fire(){
            System.out.println("fire");
        }
    }
}

但是如果內部類寫在了方法里,這里有一個問題需要注意:

public class InnerClassDemo {
    public static void main(String[] args){
        Car2 c = new Car2();
        c.run();
    }
}

class Car2{
    public String color = "red";
    public int tires;

    public void run(){
        // 這里的key必須是final 字段
        final String key = "ss";
        class Engine{
            public void fire(){
                System.out.println("插入鑰匙"+key);
                System.out.println("fire");
            }
        }
        new Engine().fire();
        System.out.println("running.....");
    }


}

抽象類

抽象類的定義: 抽象就是從多個事物中將共性的,本質的內容抽取出來 java 中可以定義沒有方法體的方法,該方法的具體實現交給子類完成該 方法稱為抽象方法,包含抽象方法的類就是抽象類

抽象類和抽象方法必須用abstract關鍵字修飾 抽象方法只有方法聲明,沒有具體的方法體,定義在抽象類中 抽象類不可以被實例化,也就是不能用new創建對象 抽象類通過其子類實例化,而子類需要覆蓋掉抽象類中所有的方法后才可以創建對象,否則該子類也是抽象類

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM