9 y% O+ B2 F$ E* }}- T2 A \. U7 E& Z4 b% s
# ?$ c1 a7 f5 E4 C ~
注意:如类声明语句中没有extends子句,则该类为java.lang包中的Object的子类。这就说明了java中的代码其实都有一个继承的关系,只不过是继承Object这个java中最根本的父类。, W1 b7 P. Y' U2 N3 `0 j! f1 j
* }9 x5 [+ t9 l
继承的特点/ G8 E# E3 w2 ]; t; f0 ~
/ C5 Z1 J% z4 K4 A/ s6 `4 Q2 n: m0 F子类拥有父类非private的属性和方法,子类继承的父类方法和成员变量可以当作自己的方法和成员变量一样被子类的实例方法使用。7 N. a/ ~9 k2 _& p9 b* N4 Y' i
子类可以有自己属性和方法,即子类可以在父类的基础上对父类进行扩展。3 S' U0 a: b- y. o8 {6 o
子类可以用自己的方式实现父类的方法。(重写或者覆盖) + o' X+ H9 U, O3 ~; B. P
访问权限和继承之间的关系 k- N; {1 p" o. G3 l
* N( {- B3 [2 O# v H; b, i访问限制修饰符限制对象对成员变量操作和方法调用,也限制继承性# x8 L) \ _8 {2 D9 J. b4 f
" P2 Z x- @4 Q f当子类和父类在同一个包:父类private成员变量和方法不会被子类继承4 J# G2 S# }" v4 M
当子类和父类不在同一个包:父类private和friend(默认)成员变量和方法不会被子类继承 & m, v- `% J* k4 l# a: @' _- w/ k
' O6 d- V& g/ o* d7 Z5 x/ U 7 G! `4 O, g" `构造器对继承的影响 / ]) g6 U9 v! F9 z 0 C3 c% ?/ P5 V7 a/ U什么是构造器: # u" e$ ^( t9 O- W. g/ s
0 z* E% e6 a4 `1 ^; X" K与一般方法名不同的是,构造方法名必须和类名保持一致,并且没有返回值。 8 O: Y/ b M/ k9 y. g. AJava编译器会自动创建无参构造函数,因此在类中,无参构造即使没有,我们也可省略不写。实例化对象时无需赋值。 $ u- l' T3 k" t6 a9 r倘若类中已存在有参构造函数,则编译器不再提供默认无参构造。实例化对象时需赋值,不然报错。 7 [( H+ t c# l. I8 x当类实例化一个对象时会自动调用构造方法。6 n+ J; e) ^" ^3 Z4 [; E4 d( g3 N
构造器在Java的继承中会产生什么影响呢?3 W* J- d; E+ V0 n5 }4 l8 ~7 V' V
7 N6 c( N I/ R0 W) s% I7 R5 o
我们虽然继承了父类但是父类的构造器是我们子类继承不了的,我们只能去调用父类的构造器。那么在继承并且编写子类的构造方法的时候就要注意两种情况了:1.父类没有重写了构造函数(即构造函数是Java默认给的一个构造函数);2.父类重写了构造函数。 7 N: m5 T3 M" Z" R
) k- n& F5 Y& x! o$ |' m
父类使用默认构造器1 [2 _. ]. o& e5 d! n" K( D% U
N* Q0 P; x" f3 v, u7 K' }: ~
package Extends; ! G) O' m0 f' j6 N/ u1 ?2 x. ~# [, S% V; i6 p/ n& f5 f
public class Father {* [2 f, M; L9 G# z
Father(){ //默认的看不出区别所以这边设置个无参构造器效果一样的 7 l+ `! N4 z% |- [ //当你不定义的时候就是这个构造器 - m0 Y6 P2 L8 Q- V System.out.println("This is Father Constrctor");) V0 ?5 Q/ C# I
}# k8 \+ {: v* J+ j3 @ q {' ^9 g
} " E( T6 U6 z) Tpackage Extends;8 K. D% L& J- d4 ^5 m% P
3 s; [! i3 ^! H$ [
public class Nosuper extends Father{- @$ w. C3 ~5 S$ K# Y- e3 o
Nosuper(){ //定义子类的构造器 . ~! T0 u/ l* p' n& m System.out.println("This is Nosuper Constrctor"); 5 Q; C% n! o [ }1 b1 y1 ?8 K T6 A. `
- z$ X2 Z6 z4 l, K& `8 v
public static void main(String[] args) {2 I1 j. V: w( I1 V3 x: a1 S) z5 N
// TODO Auto-generated method stub - b! s: A; S3 u0 R& l Nosuper no=new Nosuper(); & \' I0 S& Z+ o$ J" z( U }1 t6 O! ]0 } Z5 F
1 {1 k% m& g5 Z}( p: T$ K# d1 ^
OUTPUT:- ~" ^. b2 D4 _, K0 F. V
This is Father Constrctor9 Z! y3 n: u, c C! t. k' `& ?
This is Nosuper Constrctor ' n" `4 k# [" s' u7 R& L" I父类不使用默认构造器5 f( l3 ]* E q0 s
! R# J+ j" f# y5 T" e; [4 }1 N. Spackage Extends; 7 n, Z: L) C" H3 t& i/ ~9 e/ {! L- \6 T5 N$ z/ p
public class Father { ^, m4 M* W2 I Father(String name){) D0 |2 Z6 P( {$ c
System.out.println("This is Father Constrctor,name is "+name);& U7 E. Z2 l! f7 {: `8 N
} $ s7 g( j9 E/ D" K$ N}8 I2 l1 i# Q. T: G
package Extends; 7 }9 a* b! s0 w6 _ % H. y) j0 o! T9 P! C- \, v4 k, \public class Nosuper extends Father{ * [3 I1 \6 Y+ X2 r( C/ u Nosuper(){ 7 L' f0 _9 T/ H: ^ super("YYH"); //必须先调用父类的构造函数否则会报错5 E: O* A/ b: U3 E- Q3 E+ \, r2 W5 u
System.out.println("This is Nosuper Constrctor");, n8 \8 Z% n6 Z! e1 d9 f$ D
} 0 X- |3 M' l4 k) X8 H! q* r- H public static void main(String[] args) { 9 u: E. ~1 i& X; f2 G- G: S; q- p // TODO Auto-generated method stub 4 [. r, A. n% @/ X, `4 X Nosuper no=new Nosuper(); ' f1 W1 a d& n0 ~2 @$ N+ V } 3 e' H1 H. k7 [! v: v: \4 t6 }}$ L3 u# P0 l6 X- T+ a
OUTPUT:# ^$ k- H6 e9 h: @ \3 h$ x+ f
This is Father Constrctor,name is YYH " H( s% L# z. H* sThis is Nosuper Constrctor # I- _! G5 A* g- t+ a- h总结:对于继承来说,子类会默认调用父类的构造器,但是如果没有默认的父类构造器,子类必须要调用父类的构造器,而且必须是在子类构造器中做的第一件事(第一行代码)。 + z$ e& S( N* p% S3 Y, r) V! J; ^" k z" }+ m0 j' D
. _3 U# [6 j; V# V5 _& H