物件導向概念
類:類是一個模板,表示一類事物的行為和狀態
物件:物件是類的一個例項,有自己狀態和行為
類是物件的抽象,而物件是類的具體例項。
class Person{
public String name;
public int age;
public static int legs=2;
Person(String name,int age){
this.name=name;
this.age=age;
}
public void eat(){
System.out.println("吃飯");
}
}
------------
Person zhangsan=new Person("張三",21);
Person lisi=new Person("李四",22);
複製程式碼
Person是類 類中有name和age屬性預設是空的 行為方法:eat
zhangsan和lisi分別是Person的一個具體的類,有自己的name和age,和類的行為方法eat
構造方法
顧名思義,非普通方法,具有構造功能,通過此方法可以構造物件
構造方法的方法名必須與類名一樣。
構造方法沒有返回型別,也不能定義為void,在方法名前面不宣告方法型別。
構造方法主要作用是完成物件的初始化工作,他能夠把定義物件時的引數傳遞給物件的域。
構造方法不能由程式設計人員呼叫,而要系統呼叫。
構造方法可以過載,以引數的個數,型別,或排序順序區分。
當我們使用new Person("張三",21)時,實際上系統會自動呼叫 Person(String name,int age)構造方法
複製程式碼
所有的構造方法,都要直接或者間接的呼叫父類的構造方法,因為先有父類才會有子類。
Object是所有類的直接或間接父類。上面的構造方法實際會隱式呼叫super() 即Obejct的空引數構造方法
Person(String name,int age){
super();//隱式呼叫
this.name=name;
this.age=age;
}
複製程式碼
類屬性和物件屬性
由static修飾的屬性即類屬性,沒有static修飾即物件屬性
類屬性,可以通過 類.屬性名 來引用 也可以使用 物件.屬性名 來引用不過推薦
物件屬性 必須通過 物件.屬性名 來引用
Person zhangsan=new Person("張三",21);
Person lisi=new Person("李四",22);
zhangsan.age=30;//並不會影響李四的age
System.out.println(lisi.age);// 22
//Person有一個屬性 public static int legs=2; 兩隻腿
zhangsan.legs=1;
//修改張三的腿數量 李四的同樣會變 為避免不必要的麻煩,一般使用Person.legs來引用
System.out.prinln(lisi.legs);//1
複製程式碼
類方法和物件方法
同屬性一樣,由static修飾的即類方法,沒有則普通方法
類方法,可以通過 類.方法名 來引用 也可以使用 物件.方法名 來引用不過推薦
物件方法 必須通過 物件.方法名 來引用
繼承和實現
子類是父類的一種,子類具有父類的屬性和方法,同時還具備自己的屬性和方法
子類是通過extends來實現的,java中只支援單繼承。父類可以是一般類或者是抽象類,通過final修飾的類,不能被繼承
抽象類:一種特殊的類,類中可以有抽象方法,抽象類不可被例項化
public abstract class Anim{
public abstract void eat();//抽象方法
}
複製程式碼
注:抽象類也可以沒有抽象方法,唯一的作用是不讓類被例項化
介面:一種特殊的抽象類
public interface Lived{
void living();
}
複製程式碼
介面中所有的方法都是抽象的並且是public的,所有的成員都是常量。從java8.0開始介面中可以定義預設方法 預設方法子類不需要實現
實現介面通過implements 來實現,java中支援多實現。
public class Person extends Anim implements Lived{
@Override
public void living(){
System.out.println("群居生活");
}
@Override
public void eat(){
System.out.println("每天吃三頓");
}
}
複製程式碼
一個類如果不是抽象的,必須實現所有介面的全部方法和父類的全部抽象方法
方法的重寫和過載
重寫:覆蓋父類的方法,定義自己的實現。方法名,方法引數,返回值必須相同。子類方法的許可權範圍不能小於父類
過載:相同的方法,不同的引數。方法名相同,返回值可以不同。範圍修飾符可以不同
重寫只有父子類才會發生的。 過載可以在一個類 也可以在父子類
物件初始化流程
public class Test2 {
public static void main(String[] args) {
B b = new B();
System.out.println("-------------------------");
b = new B();
}
static class A {
public String content = "AA";
public static String text = "父類的Text";
{
System.out.println("父類程式碼塊");
}
static {
System.out.println("父類靜態程式碼塊");
}
A() {
System.out.println("父類構造方法");
}
}
public static class B extends A {
public String con = "BB";
public static String textA = "子類的Text";
{
System.out.println("子類程式碼塊");
}
static {
System.out.println("子類靜態程式碼塊");
}
B() {
System.out.println("子類構造方法");
}
}
}
複製程式碼
父類靜態程式碼塊
子類靜態程式碼塊
父類程式碼塊
父類構造方法
子類程式碼塊
子類構造方法
-------------------------
父類程式碼塊
父類構造方法
子類程式碼塊
子類構造方法
物件的初始化流程:
第一次建立物件
1.父類的靜態變數和靜態程式碼塊
2.子類的靜態變數和靜態程式碼塊
3.父類的普通變數和程式碼塊
4.父類的構造方法
5.子類的普遍變數和程式碼塊
6.子類的構造方法
第二次建立物件
1.父類的普通變數和程式碼塊
2.父類的構造方法
3.子類的普遍變數和程式碼塊
4.子類的構造方法
多型
父類引用指向子類物件,即同一類的引用可以表現不同行為。
例如:人繼承動物
人可以指向動物 即人物件指向動物引用,反過來說則不合適,動物不能指向人,因為動物不只是人。
public class Manager {
public static void main(String[] args) {
Anim anim = new Anim();
System.out.println("anim--->name:" + anim.name);
System.out.println("anim--->age:" + anim.age);
anim.eat();
anim.wan();
System.out.println("----------------------");
Anim pig = new Pig();
System.out.println("pig--->name:" + pig.name);
System.out.println("pig--->age:" + pig.age);
pig.eat();
pig.wan();
System.out.println("----------------------");
Anim dog = new Dog();
System.out.println("dog--->name:" + dog.name);
System.out.println("dog--->age:" + dog.age);
dog.eat();
dog.wan();
System.out.println("----------------------");
Dog dog2= (Dog) dog;
System.out.println("dog--->name:" + dog2.name);
System.out.println("dog--->age:" + dog2.age);
dog2.eat();
dog2.wan();
dog2.sleep();
}
static class Anim {
public String name = "動物";
public static int age = 0;
public void eat() {
System.out.println("動物的eat方法");
}
public static void wan() {
System.out.println("動物的靜態 玩方法");
}
}
static class Pig extends Anim {
public String name = "小豬";
public static int age = 5;
@Override
public void eat() {
System.out.println("小豬的eat方法");
}
public static void wan() {
System.out.println("小豬的靜態 玩方法");
}
}
static class Dog extends Anim {
public String name = "小狗";
public static int age = 3;
@Override
public void eat() {
System.out.println("小狗的eat方法");
}
public static void wan() {
System.out.println("小狗的靜態 玩方法");
}
public void sleep(){
System.out.println("小狗的 sleep方法");
}
}
}
複製程式碼
輸出結果:
anim--->name:動物
anim--->age:0
動物的eat方法
動物的靜態 玩方法
----------------------
pig--->name:動物
pig--->age:0
小豬的eat方法
動物的靜態 玩方法
----------------------
dog--->name:動物
dog--->age:0
小狗的eat方法
動物的靜態 玩方法
----------------------
dog--->name:小狗
dog--->age:3
小狗的eat方法
小狗的靜態 玩方法
小狗的 sleep方法
複製程式碼
由上面程式碼執行結果可見:
普通變數,靜態變數,靜態方法看 左側
普通方法 看右側
父類引用指向子類物件,不能呼叫子類中宣告而父類中沒有宣告的方法和變數