; c" k+ a5 T6 i3 \0 k/ ~我们虽然继承了父类但是父类的构造器是我们子类继承不了的,我们只能去调用父类的构造器。那么在继承并且编写子类的构造方法的时候就要注意两种情况了:1.父类没有重写了构造函数(即构造函数是Java默认给的一个构造函数);2.父类重写了构造函数。 . p+ b/ v, D/ r# w. g' w' Z * S0 z. g% v+ d/ x父类使用默认构造器 # D# r9 _' _" q' s. G5 l% z& J3 ?& C2 J$ t* b0 B& y# n
package Extends; ' _. x# d9 y% J4 \( G % M" B# r, ], D1 v9 J" h6 U8 Fpublic class Father { U* n. B; W3 Y) c Father(){ //默认的看不出区别所以这边设置个无参构造器效果一样的 ; b. M- L" w, z //当你不定义的时候就是这个构造器 - L/ B8 g; d8 L% h5 N9 N# @( b l+ z System.out.println("This is Father Constrctor"); $ v* o4 F* F# M. I } 0 w7 ?. p) w, l& K4 w} * Z% L8 h& q; wpackage Extends;, [- F+ u) m) E9 q( \. s8 g
1 k( y/ S, H4 R* u; w% u spublic class Nosuper extends Father{ $ O, @5 |: S% W8 f. ~: O Nosuper(){ //定义子类的构造器. n, U. z: w+ z
System.out.println("This is Nosuper Constrctor"); p; _( l6 O8 a3 H8 z
}. J( a9 u9 P+ v% x6 `% n
) L7 ~; \! z. x& ` public static void main(String[] args) { 1 {5 X' ^, n* O6 L/ G // TODO Auto-generated method stub $ K1 ~! t P& A/ A4 { H Nosuper no=new Nosuper();9 T$ d( y0 ?; a
} O( X3 u* W# q4 m
' E3 |$ M+ q) W7 c+ K! G$ T. H- q
}5 ~ E v& L$ V
OUTPUT: ; r! r9 K$ |1 y% ]5 a+ vThis is Father Constrctor 4 u) H/ r6 z) E& j/ \: X9 }This is Nosuper Constrctor) ]1 C3 { t+ f: L8 H( c* K
父类不使用默认构造器 " N- s$ b) o. t/ ~$ y 7 T6 G& \+ s: N0 l7 E$ z$ `package Extends;& m# w% F D2 F' o: T; C" I
9 T7 @* d: H- ]public class Father {# m; {+ [8 z( b' Y7 v! P! ]
Father(String name){ & p7 E: |- l* B0 @; e6 ~+ m System.out.println("This is Father Constrctor,name is "+name); . n' y! \; d# x4 U, W }% l+ D" U/ l5 L9 U {. ?
}& J' q- f2 h! _5 T' G8 O" `% i! C
package Extends;8 O( `( a1 A, I" \! E/ z
! r' e" ` l& w6 ipublic class Nosuper extends Father{ . x: O. C) P0 p9 h' A: m8 }9 u Nosuper(){ 9 p- z" u4 I+ d" z% ]3 T: R
super("YYH"); //必须先调用父类的构造函数否则会报错8 p6 e- e6 x R$ J
System.out.println("This is Nosuper Constrctor"); " }: u; o6 |# B" [. M: L- K# x }6 U! q D1 [( p) e4 S- Q2 s: a
public static void main(String[] args) {: m: P1 J5 V& v m1 S* l
// TODO Auto-generated method stub 0 L+ h7 K( J( o Nosuper no=new Nosuper(); 2 ~5 I* z1 X4 V6 B } . J+ T" ~$ x; x} + n" _5 C( n4 ?5 g4 G( B& `OUTPUT: ' H' }3 t! Q% l" r/ \& ^9 jThis is Father Constrctor,name is YYH, e. f5 W# m: a( }# \
This is Nosuper Constrctor " [$ [; U& [3 ?$ y总结:对于继承来说,子类会默认调用父类的构造器,但是如果没有默认的父类构造器,子类必须要调用父类的构造器,而且必须是在子类构造器中做的第一件事(第一行代码)。 ) P: c; m! c- s# \$ S! \* A ~3 M7 z5 q; [# q 5 T) C+ T6 ^& C$ Y% ~# z- \2 N/ z$ w- ]) N5 b$ C ?
继承中的向上转型 ) g2 @( i; K) B; {. r5 v& B2 O+ h0 x4 w
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。7 X: O- {% j0 G* Z1 {9 n
; ?/ }3 q: H1 ?# S1 n9 ypackage _4_8; 2 S. n, N0 y; d& D* E- B7 G" }% u9 P4 [
class A {- b& A: p5 M6 q) e" v
public String show(D obj) { - y$ G- l/ e9 _3 o% Z/ ] return ("A and D");3 e [4 v' l& j% z+ E% R0 g
} F1 i' v0 J3 u% o" O public String show(A obj) { \9 k3 A. C" q4 C) N
return ("A and A"); 6 L1 b: g: A4 M8 S' Z! X } & ?: j. H9 i1 S5 q0 @9 l5 F7 A; K
} 8 T3 K8 c/ N# C+ k* L7 A1 Q3 j" H1 \' y4 b- p* c* `# L" h2 w! O4 \5 u
+ T! ~7 V* M. Y; n& ~6 vclass B extends A{# K, _. A8 w5 |* y# C: _) R
//重载 * c3 y$ |' z% s, u) e) ^ 6 E1 {, U, D" \* {. m' J) d8 T
public String show(B obj){ G1 S7 g2 F( B+ B# \( s3 q
return ("B and B"); ' O5 u1 k/ L5 A/ z3 F/ u' W }0 N% f2 H- M; n" I" p0 l+ x( |
//重写 - W4 i* e1 j% A3 T+ V public String show(A obj){ ~8 R4 d/ f& u; u) [# u9 N( z
return ("B and A"); # |( P/ o* H+ C4 X8 u9 | } 6 w) j+ J/ d, o , w, x. H- K+ B} * u( [9 w8 v$ z8 c t & Z6 q5 }) F2 p1 b0 G! }$ q+ O3 M1 G3 L% f0 X& \6 b v7 N
class C extends B{} 9 L& x% v% p# Bclass D extends B{}$ L5 Y t- L' H; `3 a/ j
public class t {+ w4 P# M: m+ D8 w" C7 H; q7 m+ U
public static void main(String[] args) {# I+ P7 q" H+ T5 B- Y
A a1 = new A();1 M+ T% C% ]7 n. S
A a2 = new B(); //1.只能调用子类中重写父类的方法,不可以 , g) v1 g6 C1 ^- Z6 A% b //调用重载的方法 8 d5 \3 y) ?3 ~# S% S9 f( Z B b = new B();1 y8 F* t- q H+ y) _
C c = new C(); # r. c0 c$ O; M- g D d = new D(); 4 K% G) X% e+ v$ C% u System.out.println("1--" + a1.show(b)); ; N7 g0 H0 j1 W" J9 x7 V( K: s System.out.println("2--" + a1.show(c)); ; S5 D- a" ]8 n- U- x% G System.out.println("3--" + a1.show(d)); - l5 {; k. Q+ Z) G$ X8 U* e System.out.println("--------");6 v% X: l: m! S) ^9 f# F
System.out.println("4--" + a2.show(b));! l& n4 v: Q- N9 D, V/ Y
System.out.println("5--" + a2.show(c));) ~. u' v% p7 C, k. N/ ^2 Q1 ~5 V
System.out.println("6--" + a2.show(d)); # B, N7 |2 j- E f u System.out.println("6--" + a2.show(a1)); . O& U6 C' i0 x* x: h S t System.out.println("*");" P* p+ R8 ~& T- u
System.out.println("7--" + b.show(b)); % R2 X. Z2 X8 l& E- z! p6 g, |- N System.out.println("8--" + b.show(c)); $ d% R5 Q% M& M# o6 w4 B- M5 r System.out.println("9--" + b.show(d)); $ O5 M0 s G$ u1 R } 9 q. T4 R1 Z/ b}% V( {$ E3 I! }; A4 c
OUTPUT:5 j+ L1 v4 [6 j7 W2 p6 r
1--A and A ) V# x5 U3 K2 ]3 U( u) M, V) A$ ?2--A and A : d; \. a4 q# K! Q9 y3--A and D 4 G5 G, [# F: z; h O( n-------- # s6 ^2 G B5 V4--B and A ! Y4 m+ O/ n( b' m2 }) M. j- g: l5--B and A ) n& I1 Q8 n% I6--A and D , T; q$ o" T- ?6--B and A " O: h4 g, ]. V" \% t*" ?& P# i" s' A- T- ?( r" H
7--B and B ( S, w( r! W) P8--B and B! Q( I( P/ |( t8 D# o# s) h
9--A and D ! M; ^7 ^( b, ]0 l; l5 v 仔细理解一下其中的代码不难理解其中向上转型在继承中的作用。按照this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)这个顺序一步一步的执行就会得到结果。 7 z3 }7 W% Y/ M9 ]0 ~ i % @! K% y+ V( ?8 ^, d. h将子类转换成父类,在继承关系上面是向上移动的,所以一般称之为向上转型。由于向上转型是从一个叫专用类型向较通用类型转换,所以它总是安全的,唯一发生变化的可能就是属性和方法的丢失。+ Q9 u2 p9 b4 M$ G: W