Java 封裝、繼承、多態

封裝

將類的部分信息隱藏在類內,通過提供的固定方法訪問。

訪問修飾符
訪問修飾符 本類 同包 字類 其他
private
默認
protected
public
this

this.屬性名 用來區分局部變量和成員變量

private String name;
private int age;
Student(String name , int age){
	this.name = name ;
	this.age = age;
}
//但是如果寫成name=name,就並沒有把name賦給Student

this.方法名 用來訪問本類的成員方法
this() 訪問本類的構造方法,必須放在第一條語句(如果放在最後,會覆蓋前面的)

內部類
①成員內部類

原文鏈接:https://blog.csdn.net/weixin_42762133/article/details/82890555

//每個內部類都可以獨立的繼承一個接口的實現,無論外部類是否已經繼承了某個接口的實現,對內部類沒有影響。
public class Outer entends ClassA implements FunctionA{

	public class Inner extends ClassB implements FunctionB{		
	}
}
//當內部類屬性名和外部類屬性名相同時,注意怎樣從內部訪問外部類屬性
//當外部類要訪問內部類,則新建方法,在方法裏面new內部類對象,通過對象訪問

/**
 * 外部類、成員內部類的定義
 */
public class Outer {

    private int outerVariable = 1;
    private int commonVariable = 2;
    private static int outerStaticVariable = 3;
    //省略getter/setter
     
    /**
     * 成員方法
     */
    public void outerMethod() {
        System.out.println("我是外部類的outerMethod方法");
    }

    /**
     * 靜態方法
     */
    public static void outerStaticMethod() {
        System.out.println("我是外部類的outerStaticMethod靜態方法");
    }

    /**
     * 內部類
     */
    public class Inner {
    
        private int commonVariable = 20;

        /**
         * 構造方法
         */
        public Inner() {
        }

        /**
         * 成員方法,訪問外部類信息(屬性、方法)
         */
        public void innerShow() {
            //當和外部類衝突時,直接引用屬性名,是內部類的成員屬性
            System.out.println("內部的commonVariable:" + commonVariable);
            //內部類訪問外部屬性
            System.out.println("outerVariable:" + outerVariable);
            //當和外部類屬性名重疊時,可通過外部類名.this.屬性名
            System.out.println("外部的commonVariable:" + Outer.this.commonVariable);
            System.out.println("outerStaticVariable:" + outerStaticVariable);
            //訪問外部類的方法
            outerMethod();
            outerStaticMethod();
        }
    }
    
    /**
     *	外部類訪問內部類信息
     */
    public void outerShow() {
        Inner inner = new Inner();
        inner.innerShow();
    }
}

//在其他類中,創建外部類對象,通過外部類創造內部類對象

/*
*	其他類使用成員內部類
 */
public class Other {
    
    public static void main(String[] args) {
        //外部類對象
        Outer outer = new Outer();
        //創造內部類對象
        Outer.Inner inner = outer.new Inner();
        inner.innerShow();
        /*
        * 可在Outer中定義get方法,獲得Inner對象,那麼使用時,只需outer.getInnerInstance()即可。
        * public Inner getInnerInstance(Inner類的構造方法參數){
        *   return new Inner(參數);
        * }
        */
    }
}
②靜態內部類
//靜態內部類的方法只能訪問外部類的static關聯的信息。
//訪問內部類的靜態信息,直接外部類.內部類.靜態信息就可以了。
//靜態內部類可以獨立存在,不依賴於其他外圍類。
public class Outer {
	static {
        System.out.println("Outer的靜態塊被執行了……");
    }
    public static class Inner {
		public void innerShow() {
            System.out.println("innerVariable:" + innerVariable);
            System.out.println("內部的commonVariable:" + commonVariable);
            System.out.println("outerStaticVariable:"+outerStaticVariable);
            outerStaticMethod();
        }
        public static void innerStaticShow() {
        	//被調用時會先加載Outer類
            outerStaticMethod();
            System.out.println("outerStaticVariable"+outerStaticVariable);
        }
	}
}
③局部內部類
//類前不能有訪問修飾符。
//僅在方法內使用。
//可以直接訪問方法內的局部變量和參數但是不能更改。
//可以隨意的訪問外部類的任何信息。
public class Outer{
	private int outa = 1;
	public void outerMethod(){
		System.out.println("我是外部類的outerMethod方法")
	}
	public void outerCreatMethod(int value) {
		class Inner{
			private int innerVariable = 10;
            private int commonVariable = 20;
			/**
			*	局部內部類方法
			*/
            public void innerShow() {
                System.out.println("innerVariable:" + innerVariable);
                //調用外部類的信息
                System.out.println("outerVariable:" + outerVariable);
                System.out.println("內部的commonVariable:" + commonVariable);
                System.out.println("外部的commonVariable:" + Outer.this.commonVariable);
                System.out.println("outerStaticVariable:" + outerStaticVariable);
                outerMethod();
                outerStaticMethod();
            }		
		}
	}
	//入口
	public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outerCreatMethod(100);
    }
}
④匿名內部類
/**
 *   定義接口
 * 接口中方法默認爲public 
*/
public interface IAnimal{
	void speak();
}
/**
 * 外部內、內部類
*/
public class Outer {
    public static IAnimal getInnerInstance(String speak){
        return new IAnimal(){
            @Override
            public void speak(){
                System.out.println(speak);
            }};
        	//注意上一行的分號必須有
    }
    public static void main(String[] args){
    	//調用的speak()是重寫後的speak方法。
        Outer.getInnerInstance("小狗汪汪汪!").speak();
    }
}

繼承

特性:
  • 子類擁有父類非private的屬性、方法
  • 子類可以對父類擴展
  • 子類可用自己的方式實現父類的方法
  • Java可以多重繼承,但是是單繼承
  • 提高了類之間的耦合性
關鍵字
  • extends
  • implements
//可以間接實現多繼承的特性
public interface A{}
public interface B{}
public class C implements A,B{}
  • super與this
this.function();//調用自己的方法
super.function();//調用父類的方法
  • final
//可以把類定義爲不能繼承的,即最終類;或者用於修飾方法,但是該方法不能被子類重寫
final class 類名{}
構造器

原文鏈接:https://blog.csdn.net/li_jeremy/article/details/79294699

  • 創建構造器的規則
    ①構造函數名和類名相同
    ②構造函數沒有顯式返回值
  • 構造函數類型
//無參數
//顯示默認值的默認構造函數
class Student3 {
    int id;
    String name;
    void display() {
        System.out.println(id + " " + name);
    }
    public static void main(String args[]) {
        Student3 s1 = new Student3();
        Student3 s2 = new Student3();
        s1.display();
        s2.display();
    }
}
//輸出結果有值爲0 null ,編譯器自動提供默認構造函數,它爲id和name分別提供了0和null。
//有參數
class Student4 {
    int id;
    String name;
    Student4(int i, String n) {
        id = i;
        name = n;
    }
    void display() {
        System.out.println(id + " " + name);
    }
    public static void main(String args[]) {
        Student4 s1 = new Student4(111, "Karan");
        Student4 s2 = new Student4(222, "Aryan");
        s1.display();
        s2.display();
    }
}
  • 構造函數重載
Student5(int i, String n) {
        id = i;
        name = n;
    }
Student5(int i, String n, int a) {  //通過參數的不同告知編譯器此處用到了構造函數的重載
        id = i;
        name = n;
        age = a;
    }
  • 拷貝構造函數
//通過構造函數
Student6(int i, String n) {
        id = i;
        name = n;
    }
Student6(Student6 s) {  //參數傳入的是類對象
        id = s.id;
        name = s.name;
    }
public static void main(String args[]) {
        Student6 s1 = new Student6(111, "Karan");
        Student6 s2 = new Student6(s1);    //將上面的s1傳入
    } 
//將對象值分配給另一個對象
Student7(int i, String n) {
        id = i;
        name = n;
    }
Student7() {}
public static void main(String args[]) {
        Student7 s1 = new Student7(111, "Karan");
        Student7 s2 = new Student7();
        s2.id = s1.id;  //直接賦值
        s2.name = s1.name;
    }
Object類

Object類是所有類的父類,其中的方法適合所有子類

  • toString()
  • equals()

多態

原文鏈接:https://www.runoob.com/java/java-polymorphism.html

優點
  • 消除類型之間的耦合關係
  • 可替換性
  • 可擴充性
  • 接口性
  • 靈活性
  • 簡化性
三個必要條件
  • 繼承
  • 重寫
  • 父類引用指向子類對象
//使程序有良好的擴展,並可以對所有類的對象進行通用處理
public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 對象調用 show 方法
      show(new Dog());  // 以 Dog 對象調用 show 方法
                
      Animal a = new Cat();  // 向上轉型  
      a.eat();               // 調用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下轉型  
      c.work();        // 調用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 類型判斷
        if (a instanceof Cat)  {  // 貓做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃魚");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨頭");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}
  • 重寫
//當子類對象調用重寫的方法時,調用的是子類的方法,而不是父類中被重寫的方法
//若要調用父類中被重寫的方法,必須使用關鍵字super
多態的實現方式
重寫

原文鏈接:https://www.runoob.com/java/java-override-overload.html

//必須是重寫父類已有的方法
class Animal{
   public void move(){
      System.out.println("動物可以移動");
   }
}
 
class Dog extends Animal{
   public void move(){
      System.out.println("狗可以跑和走");
   }
   public void bark(){
      System.out.println("狗可以吠叫");
   }
}
 
public class TestDog{
   public static void main(String args[]){
      Animal a = new Animal(); // Animal 對象
      Animal b = new Dog(); // Dog 對象
 
      a.move();// 執行 Animal 類的方法
      b.move();//執行 Dog 類的方法
      b.bark();		/////////////////////////bark在父類裏面並沒有,報錯
   }
}

重寫規則:

  • 參數列表必須完全與被重寫方法的相同
  • 返回類型與被重寫方法的返回類型可以不相同,但是必須是父類返回值的派生類
  • 訪問權限不能比父類中被重寫的方法的訪問權限更低
  • 聲明爲 final 的方法不能被重寫
  • 聲明爲 static 的方法不能被重寫,但是能夠被再次聲明
  • 構造方法不能被重寫
  • 如果不能繼承一個方法,則不能重寫這個方法
重載

被重載的方法必須改變參數列表(參數個數或類型不一樣)

public String test(int a,String s){
        System.out.println("test3");
        return "returntest3";
    }   
public String test(String s,int a){
        System.out.println("test4");
        return "returntest4";
    }   

在這裏插入圖片描述

接口

除非實現接口的是抽象方法,否則要實現接口中的所有方法

抽象類和抽象方法

抽象類:一個類中沒有包含足夠的信息來描繪一個具體的對象
抽象方法:方法的具體實現又子類確定

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章