Java面向物件的三大特徵以及理解
Java面向物件的三大特徵為:封裝、繼承和多型,本文說說我對三大特性的理解。
1.封裝
Java中的封裝是指一個類把自己內部的實現細節進行隱藏,只暴露對外的介面(setter和getter方法)。封裝又分為屬性的封裝和方法的封裝。把屬性定義為私有的,它們通過setter和getter方法來對屬性的值進行設定和獲取。下面我舉一個簡單的封裝例子
public class Person { private int id; private String name; private Person person; public int getId() { return id; } public String getName() { return name; } public Person getPerson() { return person; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setPerson(Person person) { this.person = person; } }
在Person類中,定義了三個成員變數,分別為id name person,它們的訪問修飾都是private私有的,通過setter和getter方法對這些變數進行設值以及取值。那麼這麼做有什麼好處呢?封裝的意義就是增強類的資訊隱藏與模組化,提高安全性。封裝的主要作用也是對外部隱藏具體的實現細節,增加程式的安全性。
2.繼承
Java中的繼承是指在一個現有類(父類)的基礎上在構建一個新類(子類),子類可以擁有父類的成員變數以及成員方法(但是不一定能訪問或呼叫,例如父類中private私有的成員變數以及方法不能訪問和呼叫)。繼承的作用就是能提高程式碼的複用性。子類擁有父類中的一切(擁有不一定能使用),它可以訪問和使用父類中的非私有成員變數,以及重寫父類中的非私有成員方法。
父類:
package cn.csu.ksh; public class Person { private int a=1;//父類私有成員變數 private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; } public void say() { System.out.println("person say.."); } public void run() { System.out.println("person run...."); } //父類的私有方法 private void show() { System.out.println("person show..."); } }
子類:
package cn.csu.ksh; public class Student extends Person { @Override public void say() { super.say(); } @Override public void run() { super.run(); } public static void main(String[] args) { Student stu = new Student(); //stu.a=1;//子類物件對父類的私有成員變數使用報錯! //stu.show();//子類物件呼叫父類的私有方法,同樣報錯! stu.say(); stu.run(); } }
繼承的好處是實現程式碼的複用以及擴充套件,子類通過對父類程式碼的複用,可以不用再定義父類中已經定義的成員變數,方法上直接對父類的方法進行重寫實現了擴充套件。
多型
多型就是指多種狀態,就是說當一個操作在不同的物件時,會產生不同的結果。
在Java中,實現多型的方式有兩種,一種是編譯時的多型,另外一種是執行時多型,編譯時的多型是通過方法的過載實現的,而執行時多型是通過方法的重寫實現的。
方法的過載是指在同一個類中,有多個方法名相同的方法,但是這些方法有著不同的引數列表,在編譯期我們就可以確定到底呼叫哪個方法。
方法的重寫,子類重寫父類中的方法(包括介面的實現),父類的引用不僅可以指向父類的物件,而且還可以指向子類的物件。當父類的引用指向子類的引用時,只有在執行時才能確定呼叫哪個方法。
其實在執行時的多型的實現,需要滿足三個條件:1.繼承(包括介面的實現)2.方法的重寫 3.父類的引用指向子類物件
並且,我們說的多型都是類中方法的多型,屬性是沒有多型性的。方法的過載我這裡就不舉例說明了,我說一下執行時的多型。
介面
package cn.csu.ksh;
public interface Animal {
void shout();
}
實現類
package cn.csu.ksh;
public class Dog implements Animal{
@Override
public void shout() {
System.out.println("wangwang...");
}
}
實現類
package cn.csu.ksh;
public class Cat implements Animal {
@Override
public void shout() {
System.out.println("miaomiao...");
}
}
測試:
package cn.csu.ksh;
public class AnimalTest {
public static void main(String[] args) {
//父類的引用指向子類物件
Animal d = new Dog();
animalShout(d);
//父類的引用指向子類物件
Animal c= new Cat();
animalShout(c);
}
public static void animalShout(Animal animal) {
animal.shout();
}
}