继承
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
在Java之中,如果要实现继承的关系,可以使用如下的语法:
class 子类 extends 父类 {}
子类又被称为派生类; 父类又被称为超类(Super Class)。
继承的实现
class Base{//基类
public int ma;
static{
System.out.println("Base.static init!!");
}
{
System.out.println("Base.instance init!!!");
}
public Base(int a){
System.out.println("Base init!!!");
this.ma = a;
}
}
class Derive extends Base{//子类
private int mb;
static{
System.out.println("Derive.static init!!");
}
{
System.out.println("Derive.instance init!!!");
}
子类继承了父类除构造函数之外的其他数据成员及方法。
我们可以通过以下命令来调用父类中的方法与数据
super(): 调用基类的构造函数
super.data: 访问我基类的数据成员
super.func(): 访问我基类的成员方法
对象是如何产生:
1、先为对象分配内存
2、调用合适的构造函数
基类的初始化过程:
1,静态数据成员
2,静态代码初始化
3,实例数据成员
4,实例代码初始化
5,调用构造函数
子类的初始化过程:
1.基类 静态代码块
2.子类 静态代码块
3.基类 实例代码块
4.基类 构造方法
5.子类 实例代码块
6.子类 构造方法
并且不管是基类还是子类他们的static代码块只初始化一次
基类数据成员在派生类当中的访问权限
派生类和基类之间相互赋值
子类可以给父类赋值,但是父类不能给子类赋值
java编译器支持从大到小的转换
如下面代码
Base b = new Base(10);//父类对象
Derive d = new Derive(10,20);//子类对象
b = d;//编译期可以通过
d = b;//编译期无法通过
派生类和基类同名方法的关系
1,overload(重载)
即子类与父类中函数的函数名相同 ,参数列表不同 ,返回值不做要求。
class Base{
private int ma;
public Base(int a){
this.ma = a;
fun1();
}
public void fun1(){//实例方法
System.out.println("Base.fun1!!!");
}
public static void fun2(){//类方法
System.out.println("Base.fun2!!!");
}
}
class Derive1 extends Base{
private int mb;
public Derive1(int a,int b){
super(a);
this.mb = b;
}
//重载
public void fun1(int i){
System.out.println("Derive1.fun1(int)!!");
}
}
如上面代码中俩个类中的fun1方法,就是一种方法的重载
2,override(重写or覆盖)
即子类与父类中函数的函数名相同 ,参数列表相同 ,返回值相同。
class Derive2 extends Base{
private int mc;
public Derive2(int a,int c){
super(a);
this.mc = c;
fun1();
}
public void fun1(){//实例方法
System.out.println("Derive2.fun1!!!");
}
}
如上述代码就是对于fun1的覆盖,当子类调用fun1函数时
结果为:
Derive2.fun1!!!
但是这个覆盖对于父类的fun1函数并不产生影响
方法的调用过程
在方法区中每一个类都有一个方法表,方法表中存储着各种方法名称和方法所在的地址,在调用方法的时候先通过类找到其方法表,然后在方法表中找到方法所在的地址,最后再执行方法
class对象是由ClassLoader在static初始化之前生成的