示例:
public class ParentChildTest {
public static void main(String[] args) {
Parent parent=new Parent();
parent.printValue();
Child child=new Child();
child.printValue();
parent=child;
parent.printValue();
parent.myValue++;
parent.printValue();
((Child)parent).myValue++;
parent.printValue();
}
}
class Parent{
public int myValue=100;
public void printValue() {
System.out.println("Parent.printValue(),myValue="+myValue);
}
}
class Child extends Parent{
public int myValue=200;
public void printValue() {
System.out.println("Child.printValue(),myValue="+myValue);
}
}
總結:
附錄:網絡上摘取的一些代碼和解釋,可以幫助理解。
例1:
public class A {
protected String a = "1";
public String getA(){
return this.a;
}
}
public class B extends A {
protected String a = "2";
// public String getA(){
// return a;
// }
public static void main(String[] args) {
B x = new B();
System.out.println(x.getA());
}
}
輸出的是1,父類的方法看到的變量是父類中的a。
如果B中也寫一個getA方法,看到的a就是子類中的a了。
其實就是可見性的問題。
父類和子類的變量是同時存在的,即使是同名。
子類中看到的是子類的變量,父類中看到的是父類中的變量。
它們互相隱藏,而同名的方法則是實實在在的覆蓋。
如A x = new B();
x是一個B,也是一個A,
那么調用方法時,是根據對象的實際類型調用的,
實際類型是B,所以永遠調用子類的方法。
而訪問成員變量就不同了,它是B時,訪問的是子類的成員變量,
轉型為A的話,訪問的就是父類的成員變量了。
例2:
//Main.java
class c
{
public int name = 12;
}
class d extends c
{
d()
{name =13;}
void d2()
{
System.out.println(super.name);
}
}
public class Main
{
public static void main(String[]args)
{
d d1 = new d();
System.out.println(d1.name);
d1.d2();
}
}
//運行結果為:13,13
//Main1.java
class c
{
public int name = 12;
}
class d extends c
{
int name =13;
void d2()
{
System.out.println(super.name);
}
}
public class Main
{
public static void main(String[]args)
{
d d1 = new d();
System.out.println(d1.name);
d1.d2();
}
}
//運行結果為:13,12
首先要了解super這個關鍵字的意思,是調用父類的意思,
void d2()
{
System.out.println(super.name);
}這句話就是調用父類的name,雖然子類里面有一個name,但是並不是覆蓋了父類里面的name,而只是父類的name隱藏起來了,使得直接調用子類里面的name顯示的是子類定義的name。
第一個main。Java,不用說,子類沒有定義name變量,並且父類里面的name變量不是private,子類可以直接繼承name,這樣子類和父類就共用一個name變量
如果父類定義了一個方法。子類重寫了這個方法。那么這兩個方法其實也是擁有各自的內存。
例3:
class Parent{
int i=10;// 父類變量
public void setI(int i){
this.i=i;
}
}
class Son extends Parent{
int i=10;// 子類與父類同名的變量
public static void main(String args[]){
Son son=new Son();
System.out.println("son.i="+son.i);
son.setI(100);
System.out.println("After setI(100) : son.i="+son.i);
Parent parent=son;
System.out.println("See son as Parent : son.i="+parent.i);
}
}
在這段代碼中,子類定義了一個父類中同名的成員變量int i,在父類中有一個對 i 賦值的方法setI(),而在子類中沒有定義這個方法。當子類調用繼承而來的setI()方法對成員變量i進行改變,直接打印son.i時,成員變量i然而卻沒有改變。當但當把son當作Parent類型來使用,再打印它的成員變量i時,輸出的結果就對了,是setI()改變之后的值。
java中類是分層次的,當子類和父類的定義同名時,父類變量被隱藏,父類的實例方法被重寫,靜態方法屬於類級別的方法,在子類和父類中互不相礙。
例4:關於方法的重寫Overriding和重載Overloading 。
方法的重寫Overriding和重載Overloading是Java多態性的不同表現。重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。Overloaded的方法是可以改變返回值的類型。也就是說,重載的返回值類型可以相同也可以不同。
1、重載(Overloading)
a、方法重載是讓類以統一的方式處理不同類型數據的一種手段。多個同名函數同時存在,具有不同的參數個數/類型。重載Overloading是一個類中多態性的一種表現。b、Java的方法重載,就是在類中可以創建多個方法,它們具有相同的名字,但具有不同的參數和不同的定義。調用方法時通過傳遞給它們的不同參數個數和參數類型來決定具體使用哪個方法,這就是多態性。
c、重載的時候,方法名要一樣,但是參數類型和個數不一樣,返回值類型可以相同也可以不相同。無法以返回型別作為重載函數的區分標准。
2、重寫(Overriding)
a、父類與子類之間的多態性,對父類的函數進行重新定義。如果在子類中定義某方法與其父類有相同的名稱和參數,我們說該方法被重寫(Overriding)。在Java中子類可繼承父類中的方法,而不需要重新編寫相同的方法。但有時子類並不想原封不動地繼承父類的方法,而是想作一定的修改,這就需要采用方法的重寫。方法重寫又稱方法覆蓋。b、若子類中的方法與父類中的某一方法具有相同的方法名、返回類型和參數表,則新方法將覆蓋原有的方法。如需父類中原有的方法,可使用super關鍵字,該關鍵字引用了當前類的父類。
c、子類函數的訪問修飾權限不能少於父類的