能被子類繼承,若是沒有被final修飾,則能被重寫,當父類引用指向子類對象時,表現出多態性。java
不能被子類繼承,更不能被重寫,沒有多態性(有的人理解爲父類的全部包括私有的成員都能被繼承,只是在子類中不可見,我更傾向於前者)。當子類中出現與父類私有方法名和參數相同的時候會發生什麼呢?編程
class Parent{ private void f() { System.out.println("parent"); } public static void main(String[] args) { Parent p = new Child(); p.f(); } } class Child extends Parent{ public void f() { //父類的私有方法在子類中不可見,子類的f()方法是一個全新的方法,編譯器認爲f()方法沒有被重寫
System.out.println("child");
}
}
打印結果:安全
parent
靜態方法能夠被繼承,不能被重寫,也就不能表現出多態性this
class Parent{
public static void f() {
System.out.println("parent");
}
}
class Child extends Parent{
public static void f() {
System.out.println("child");
}
public static void main(String[] args) {
Parent p = new Child(); //靜態方法能被繼承,但不能被重寫
p.f();
Child c = new Child();
c.f();
}
}
打印結果:spa
parent
child
構造方法不能被繼承,不能被重寫,沒有多態性。code
構造方法既不是靜態方法也不是非靜態方法,構造方法中會有一個this對象做爲參數傳進去,因此咱們能夠在構造方法內部對對象屬性進行初始化,也能夠在構造方法內調用非靜態方法。對象
若是該非靜態方法被重寫過,那麼構造器內部會不會存在多態行爲呢?參考Java編程思想中的一個例子:blog
class Glyph {
void draw() {
System.out.println("Glyph.draw()");
}
Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
}
void draw() {
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
class RolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
在父類構造器中調用被子類重寫的非靜態方法,會發生多態行爲,但這並非咱們想要的結果,緣由以下:繼承
所以,在編寫構造器中有一條有效的準則:「用盡量簡單的方法使對象進入正常狀態;若是能夠的話,避免調用其餘方法」。在構造器中,惟一可以安全調用的是基類中的final方法(包括private方法),由於這些方法不能被子類覆蓋,也就不會出現上述的問題。get
都能被繼承(與是不是靜態的無關),不能被重寫,沒有多態性。當子類中定義了與父類相同的屬性時,子類會在不一樣的存儲空間同時保留本身的和父類的屬性
class Child extends Parent {
public static int a = 2;
public void getA() {
System.out.println("a = "+a);
}
public void ParentA() {
System.out.println("super.a = " + super.a);
}
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.a); //任何域訪問操做都由編譯器解析
Child c = new Child();
c.getA(); //直接訪問field默認會獲取本身的域
c.ParentA(); //經過super.field能獲取父類的域
}
}
我的理解爲能夠被繼承,可是不能直接訪問,能經過父類public、default、或protected方法間接訪問(也有人理解爲不能爲繼承)
class Parent {
private int a;
public Parent(int a) {
this.a = a;
}
public int getA() {
return a;
}
}
class Child extends Parent {
public Child(int a) {
super(a);
}
public static void main(String[] args) {
Child c = new Child(1);
System.out.println(c.getA()); //結果爲1
}
}
當父類和子類存在相同私有屬性時:
class Parent {
private int a;
public Parent(int a) {
this.a = a;
}
public int getA() {
return a;
}
}
class Child extends Parent {
private int a = 2;
public Child(int a) {
super(a);
}
public static void main(String[] args) {
Child c = new Child(1);
System.out.println(c.getA()); //1
System.out.println(c.a); //2
}
}
關於繼承與多態以及對象初始化過程還有不少不是很理解的地方,先記錄下來,等往後有時間研究一下java虛擬機的原理再來完善!