面向对象的特征

面向对象的特征:继承 封装 多态

继承:代码的复用

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对象里放的是当前对象的信息

最后注意的是:静态类型方法不能动态绑定


如有错误,请多多指教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值