面向对象的特征:继承 封装 多态
继承:代码的复用
1.派生类继承了基类的除了 基类的构造函数的其他数据成员
class Base{
public int ma;
public Base(int a){
this.ma = a;
}
public void show(){
System.out.println("Is show");
}
}
class Base1 extends Base{
public int mb;
public Base1(int a,int b){//报错
this.ma = a;
this.mb =b;
}
}
2.super方法
派生类中的构造函数中会报错,原因是派生类中并没有继承基类的构造函数,所以我
们这里可以采用super方法来调用基类的构造方法:
public Base1(int a,int b){
super(a);
this.ma = a;
this.mb =b;
}
注意的是super方法要写在第一行。
要调用基类的方法时 super.(方法名)
int i = super.ma;
super.show();
3.类--》对象 的初始化顺序:
(1)静态数据成员 基本类型初始化对应的0值, 引用类型:null
(2)静态代码块
( 3) 实例数据成员
(4)实例代码块
(5)调用合适的构造函数
让我们用代码了解一下:
class Base1{
public int ma;
static{
System.out.println("静态父类初始化");
}
{
System.out.println("实例父类");
}
public Base1(int a){
this.ma = a;
System.out.println("父类构造函数");
}
public void show(){
}
}
class Base2 extends Base1{
public int mb;
static {
System.out.println("静态子类初始化");
}
{
System.out.println("实例子类");
}
public Base2(int a,int b){
super(a);
int i = super.ma;
super.show();
this.ma = a;
this.mb =b;
System.out.println("子类构造函数");
}
}
public class zuoye {
public static void main(String[] args) {
// TODO Auto-generated method stub
Base1 b = new Base1(10);
}
编译结果:
4.派生类的对象初始化情况:
Base2 a = new Base2(10,10);
打印情况:
注意的是:静态代码块只初始化一次。
5,基类在派生类的访问权限
6,基类与派生类之间的赋值关系
注意 红线位置报错,说明父类不能赋给派生类,但派生类可以赋给父类;
所以我们也可以这么定义:
Base1 c = new Base2(10,10);
7,反汇编基类派生类的时候
invokevirtual (java中除了构造函数和静态函数,其他成员函数都被处理为虚函数
也就是这个英文)
invokestatic (静态函数)
8,派生类与基类方法同名的关系
overlode(重载):函数名相同,参数不同,返回值类型没有要求
override(重写和覆盖):函数名相同,参数相同,返回值类型相同
class Base1{
public int ma;
public Base1(int a){
this.ma = a;
}
public void fun1(){
System.out.println("父类实例方法");
}
}
class Base2 extends Base1{
public int mb;
public Base2(int a,int b){
super(a);
this.ma = a;
this.mb =b;
}
public void fun1(int i){
System.out.println("子类构造方法");
}
}
class Base3 extends Base1{
public int mc;
public Base3(int a,int c){
super(a);
this.mc = c;
}
public void fun1(){
System.out.println("子类构造方法");
}
}
重载:
public static void main(String[] args) {
Base1 a = new Base1(10);
Base2 b = new Base2(10,10);
a.fun1();
b.fun1(10);
}
打印结果:
重载:
public static void main(String[] args) {
Base1 a = new Base1(10);
Base3 b = new Base3(10,10);
Base1 c = new Base3(10,10);
a.fun1();
b.fun1();
c.fun1();
}
打印结果:
这里c.fun1();就是重写
这里进行反编译后会发现,c.fun1()调用的是Base1.fun()的方法,但打印出来的却
是Base3.fun()方法?
这是因为发生了动态绑定(编译期间不知道调用谁),
找c对象时,先通过方法表地地址找到class对象的地址,然后找到class对象,找到
class对象才能确定此类型到底是什么类型,因为class对象里放的是当前对象的信息。
最后注意的是:静态类型方法不能动态绑定。
如有错误,请多多指教。