1.對象轉型(casting)
一個基類的引用不可以訪問其子類對象新增加的成員(屬性和方法)
可以使用引用變量
子類的對象可以當作基類的對象來使用稱作向上轉型(upcasting),反之成為向下轉型(downcasting)
public class Animal { public String name; Animal(String name) { this.name = name; }}public class Dog extends Animal{ public String furColor; Dog(String n,String furColor) { super(n); this.furColor = furColor; }}public class Cat extends Animal{ public String eyeColor; Cat(String name,String eyeColor) { super(name); this.eyeColor = eyeColor; }}public class TestCasting { public static void main (String agrs[]){ Animal a =new Animal("coco"); Dog d = new Dog("bigblack","black"); Cat c = new Cat("smallblue","blue"); System.out.PRintln(a instanceof Animal); System.out.println(d instanceof Animal); System.out.println(c instanceof Animal); System.out.println(a instanceof Cat); a = new Dog("bigyellow","yellow"); System.out.println(a.name); System.out.println(a instanceof Animal); System.out.println(a instanceof Dog); Dog d1 = (Dog)a; System.out.println(d1.furColor); }}結果是:true
true
true
false
bigyellow
true
true
yellow
針對a = new Dog("bigyellow","yellow");的解釋:
大框為Animal對象a
針對Dog d1 = (Dog)a;的解釋:
public class TestCasting { public static void main (String agrs[]){ TestCasting test = new TestCasting(); Animal a =new Animal("coco"); Dog d = new Dog("bigblack","black"); Cat c = new Cat("smallblue","blue"); test.f(a);test.f(d);test.f(c); //一個基類的引用類型變量可以"指向"其子類的對象 } public void f(Animal a){ System.out.println("name:" +a.name); if(a instanceof Dog){ Dog dog =(Dog)a; System.out.println("furColor:"+dog.furColor); } else if(a instanceof Cat){ Cat cat =(Cat)a; System.out.println("eyeColor:"+cat.eyeColor); } }}結果是:name:coconame:bigblackfurColor:blackname:smallblueeyeColor:blue
2.動態綁定和多態
動態綁定是指“在執行期間”(而不是編譯期間)判斷所用對象的實際類型,根據其實際的類型調用其相應的方法。也就是說父類中的方法,在子類中進行了重寫,在編譯中調用了父類的方法,但是在實際的執行過程中要看,你實際new出來的對象是那個子類或者是父類,來執行相關類中的方法。
多態的條件:
摩托車和卡車繼承自car,繼承重寫后,測試類時
car mt = new 摩托車(); 1.要有繼承
2.要有重寫
3.父類引用指向子類對象 public class Animal { private String name; Animal(String name) { this.name = name; } public void enjoy() { System.out.println("叫聲......"); }}public class Dog extends Animal { private String furColor; Dog(String n, String c) { super(n); furColor = c; } public void enjoy() { System.out.println("狗叫聲......"); }}public class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c; } public void enjoy() { System.out.println("貓叫聲......"); }}public class Bird extends Animal{ Bird(){ super("bird"); } public void enjoy() { System.out.println("鳥叫聲......"); }}public class Lady { private String name; private Animal pet; Lady(String name, Animal pet) { this.name = name; this.pet = pet; } public void myPetEnjoy() { pet.enjoy(); }}public class Test { public static void main(String args[]) { Cat c = new Cat("catname", "blue"); Dog d = new Dog("dogname", "black"); Bird b = new Bird(); Lady l1 = new Lady("l1", c); //new出來的Cat對象,執行時指向Cat的enjoy方法 Lady l2 = new Lady("l2", d); Lady l3 = new Lady("l3", b); l1.myPetEnjoy(); l2.myPetEnjoy(); l3.myPetEnjoy(); }}結果是:貓叫聲......狗叫聲......鳥叫聲......
內存分析如下:
3.抽象類
用abstract關鍵字來修飾一個類時,這個類叫做抽象類;用abstract來修飾一個方法時,該方法叫做抽象方法。
含有抽象方法的類必須被聲明為抽象類,抽象類必須被繼承,抽象方法必須被重寫。
抽象類不能被實例化。
抽象方法只需聲明,而不需要實現。
有方法只需要定義不需要實現時,使用抽象,即是這個方法需要重寫時
對上述的程序作如下的修改來說明抽象類:
public abstract class Animal { private String name; Animal(String name) { this.name = name; } public abstract void enjoy();}public class Dog extends Animal { private String furColor; Dog(String n, String c) { super(n); furColor = c; } public void enjoy() { System.out.println("狗叫聲......"); }}public abstract class Cat extends Animal { private String eyesColor; Cat(String n, String c) { super(n); eyesColor = c; } public abstract void enjoy();}public class Bird extends Animal{ Bird(){ super("bird"); } public void enjoy() { System.out.println("鳥叫聲......"); }}public class Lady { private String name; private Animal pet; Lady(String name, Animal pet) { this.name = name; this.pet = pet; } public void myPetEnjoy() { pet.enjoy(); }}public class Test { public static void main(String args[]) { //Cat c = newCat("catname","blue"); //由于Cat被定義為抽象類,所以不能被實例化 Dog d = new Dog("dogname", "black"); Bird b = new Bird(); //Lady l1 = new Lady("l1",c); Lady l2 = new Lady("l2", d); Lady l3 = new Lady("l3", b); //l1.myPetEnjoy(); l2.myPetEnjoy(); l3.myPetEnjoy(); }}結果是:狗叫聲......鳥叫聲......4.final關鍵字
final的變量的值不能夠被改變(final的成員變量,final的局部變量(形參))
final的方法不能夠被重寫,final的類不能被繼承
public void m(final int j){ j =9;}
不允許這樣,這樣定義說明在m方法內部不允許改變 j的值 5.接口
接口(interface)是抽象方法和常量值的定義集合
從本質上講,接口是一種特殊的抽象類,這種抽象類中只包含常量和方法的定義,而沒有變量和方法的實現
接口中聲明的屬性默認是public static final的,也只能是public static final的
接口中只能定義抽象方法,而且這些方法默認是public的,也只能是public的
接口可以繼承其他的接口,并添加新的屬性和抽象方法
多個無關的類可以實現同一個接口,一個類可以實現多個無關的接口
與繼承關系類似,接口與實現類之間存在多態性
定義java類的語法格式:
權限修飾符
class 名字 [extends 父類][implements 接口列表]{ }
public interface Singer { public void sing(); public void sleep();}public interface Painter { public void paint(); public void eat(); public void setName(String i);}public class Student implements Singer { private String name; Student(String name) { this.name = name; } public void study() { System.out.println("studying"); } public void sing() { System.out.println(this.name + " want to sing!"); } public void sleep() { System.out.println(this.name + " want tosleep more!"); }}public class Teacher implements Singer,Painter{ private String name; public String getString() { return name; } Teacher(String name) { this.name = name; } public void setName(String name) { this.name = name; } public void teacher() { System.out.println("teachering"); } public void sing() { System.out.println(this.name + "want to sing!"); } public void sleep() { System.out.println(this.name + "want tosleep more!"); } public void paint() { System.out.println(this.name + "like painting!"); } public void eat() { System.out.println(this.name + "like eating!"); }}public class TestInterface { public static void main(String agrs[]) { Singer s1 = new Student("coco"); s1.sing(); s1.sleep(); Singer s2 = new Teacher("mimi"); s2.sing(); s2.sleep(); Painter p1 = (Painter) s2; p1.setName("nini"); p1.paint(); p1.eat(); }}結果是:
coco want to sing!
coco want tosleep more!mimi want to sing!mimi want tosleep more!nini like painting!nini like eating!
另外的,在main方法里添加一個
f(Singer s){
s.sing();
}
//只要實現了這個接口的任何一個類的對象都可以往該方法里傳 6.總結
新聞熱點
疑難解答