继承
一、1 语法:
用extends关键字来实现子类继承父类,例如: public class Sub extends Base {……}
2 构造方法的书写格式:
①语法规则:
» 方法名必须与类名相同
» 不能有返回值类型
» 不能被static final synchronized abstract和native修饰
②作用:
在创建对象时用来初始化对象
③构造方法只能通过以下方式被调用:
» 当前类的其它构造方法用this语句调用
» 当前类的父类的构造方法通过super语句调用
» 在程序中通过new语句调用
④子类构造方法有两种写法:
第一种写法:
class Base {
String s;
int i ;
public Base(String s, int i) {
this.s = s;
this.i = i;
}
}
public class Sub extends Base {
String t;
public Sub(String a,int i,String t) {//三个参数
super(a,i);
this.t = t;
}
}
在这种写法中,子类构造方法比父类的参数要多,但有一点必须注意,子类构造方法中形参的顺序要与父类中的一样,写完之后再在其后写上子类自己定义的参数。在子类构造方法中,用super调用父类构造方法并传以参数。
第二种写法:
class Base {
String s;
int i;
public Base(String s, int i) {
this.s = s;
this.i = i;
}
}
public class Sub extends Base {
String t;
public Sub(String t) {//一个参数
super(“wang”,20);
this.t = t;
}
}
这种方法与上一种方法的不同这处在于子类构造方法在用super时,直接给赋了值,且在子类构造方法中形参仅有一个
PS:构造方法不能被子类继承 ;构造方法只能被系统调用,不能被程序调用 ;若不定义,系统会自动加上一个默认的构造方法,但一旦定义了,系统便不会再为程序自动加默认的构造方法;构造方法可重载 ;子类的构造方法中有super语句时,必须作为第一条语句。
3 成员(变量和方法)的覆盖(Override)规则:
首先意识到方法覆盖是以继承为前提的
① 方法覆盖时,子类与父类的方法返回值类型、名字、参数签名(形参的类型、个数、顺序)必须完全一致
② 方法覆盖时,子类的覆盖方法的访问级别不能低于父类的被覆盖方法的访问级别(该条件只用于限制方法覆盖,变量覆盖无此要求) ③ 方法覆盖时,静态方法只能被覆盖为静态方法,非静态方法只能被覆盖为非静态方法,不能混合覆盖
④ 方法覆盖时,子类方法不能抛出比父类更多的异常
PS:在方法覆盖时,子类构造方法中的形式参数可以比基类中的被覆盖的构造方法中的形式参数多,但子类中的形式参数必须包含基类中的构造方法中所有的形式参数,并且放在前面,顺序要与基类中的一致。
4 方法重载(Overload)的规则:
首先要意识到方法重载是同一个类中的概念
»方法名必须完全一致
»参数签名(参数的类型、个数、顺序)必须至少有一项不同
PS:如果这两项都完全相同,在一个类中是不允许出现的
5 多态:
①什么是多态:
多态是在有继承、方法覆盖的前提下,一个父类引用指向多个子类对象的现象。
6 转型、具体情况怎么样:
①什么是转型:
转型是指父类引用与子类引用之间的转换
②分类:
转型分为向上转型和向下转型
向上转型指子类向父类的转型;如Base b = sub;(其中sub是子类Sub的一个对象)
向下转型指父类向子类的转型;如Sub s = (Base)b;(其中b是父类Base的一个对象,向下转型要加强制类型转换)
③具体分析:
class Base {
int x;
int y;
public Base(int x,int y){
this.x = x;
this.y = y;
}
}
class Sub extends Base {
int z;
public Sub(int x,int y,int z) {
super(x,y);
this.z = z ;
}
public static void main(String[] args) {
分别加入下面情况一、二、三、四中的代码
}
}
以上为两个类,子类与父类的转型可分为以下几种情况:
情况一:Base b = new Sub(1,2,3);
Sub s = (Sub)b;
//严格意义上说这不是向下转型,因为b本身虽是父类引用,可是指向的仍是子类对象,把一个指向子类对象的父类引用赋值给的仍是一个子类引用。
System.out.println(b.x); //能正常执行
System.out.println(b.y); //能正常执行
System.out.println(b.z); //不能通过编译
System.out.println(s.x);//能正常执行
System.out.println(s.y);//能正常执行
System.out.println(s.z);//能正常执行
在这种情况下,即父类引用指向指向子类对象时(父类中的成员变量多于子类),在子类中的定义的成员变量父类是不能访问的,须转型成子类才能访问的到。未转型之前父类能指向子类中父类已定义的变量,而仅在子类中定义的变量虽然访问不到,但也不会丢弃,当转型后仍可访问
情况二:向下转型
Base b = new Base(1,2);
Sub s = (Sub)b;//向下转型,必须加强制类型转换;
System.out.println(b.x);//可以编译,但不可以执行;
System.out.println(b.y);//可以编译,但不可以执行;
System.out.println(b.z);//不可编译;
System.out.println(s.x);//可以编译,但不可以执行;
System.out.println(s.y);//可以编译,但不可以执行;
System.out.println(s.z);//可以编译,但不可以执行;
在这种情况下,即向下转型,是不可以的。
情况三:向上转型
Sub s = new Sub(1,2,3);
Base b = s;//向上转型不用强制类型转换
System.out.println(s.x);//没问题;
System.out.println(s.y); //没问题;
System.out.println(s.z); //没问题;
System.out.println(b.x); //没问题;
System.out.println(b.y); //没问题;
System.out.println(b.z);//不可编译;丢失
情况四:
Sub s = new Base(1,2);//不能编译;