深入理解继承

创建子类对象不会创建父类对象

一、重载

在编译的时候就确定调用那个方法,编译时的多态,静态联编,其中参数名和返回值类型,访问权限不作为重载的条件
重载的条件
1. 必须出现在同一类中的不同方法
2. 方法名相同,方法签名(参数类型,参数个数,参数顺序)不同
3. 返回值或修饰符不同
其中main方法也可以重载,构造方法也可以重载

二、重写(覆盖)

父类的私有属性,方法不能被子类继承(子类空间中没有为父类私有属性开辟空间,但为public,protected属性,方法开辟了空间(也就是继承))但是在堆中为父类的私有属性开辟了空间。
可以用private final String show()和public final String show()证明
原理:final修饰的方法不可以被重写
private final String show在子类定义相同的show方法,编译不出错,因为私有方法并没有继承,因此也不会重写父类的方法
public final show 在子类定义相同的show方法,编译出错,因为公有方法被继承了,但是final修饰的方法又不能被重写,所以编译出错
重写的条件

  1. 发生在两个类,并且类之间为父子关系
  2. 方法签名(方法参数的个数,顺序和参数类型)要相同或者子类中的方法签名是父类方法签名的子签名例如父类eat(List<String> obj)方法,子类重写后的方法eat(List<Object> arg)
  3. 返回的类型是父类可替换类型(也就是父类返回类型的子类)
  4. 子类中的抛出的异常和父类相同或是父类异常的子集(子类集)
  5. 访问权限大于等于子类访问权限

三、隐藏

其中子类对父类的属性和静态方法,静态属性的重写就是隐藏
不能在子类构造方法中初始化父类私有属性但可用super对父类属性初始化,在子类方法中访问父类私有属性(两种方法)

  1. 用super调用父类的公有方法进而访问父类私有属性
  2. 调用子类继承但没有重写的父类方法进行对父类私有属性访问

四、造型(下造型)

条件:继承,上造型,下造型
Animal是Dog的父类
向上造型:(父类的引用指向子类对象) Animal animal = new Dog()此表达式就是上造型
向下造型:就是把父类的引用指向的对象换成一个子类的引用来指向,一开始就要用instanceof关键字对animal所指向的对象是否是Dog类型,否则会出现ClassCastException造型异常其中bark()方法是Dog独有的方法

if(animal instanceof Dog){
((Dog)animal).bark();
}

animal.bark()编译依然出错,其中造型后animal类型依然不变
但是其中 animal = new Wolf();时 (Dog)animal转型时就会抛出ClassCastExcption异常。

五、super和this关键字

super作用(在子类中使用,子类的父类引用)
1. super在子类中可调用父类中定义的属性和方法(可能是已经被子类覆盖的方法和属性)
2. super在子类中显示调用父类的构造
注:创建子类对象一定要调用父类构造方法,为父类中的属性初始化,若把抽象类的构造方法私有化,那么继承他的子类就不能创建对象
this作用(当前对象的地址)
3. 可以通过this区分同名的局部变量和实例变量
4. 通过this调用本类的构造方法,使得创建一个对象调用不同的构造方法
5. 当通过new关键字创建对象进行默认初始化后会返回该对象的地址,则赋给this
子类和父类创建以及初始化过程
首先在创建子类对象之前需要做的:

  1. 通过类加载器把父类加载到内存中
  2. 首先执行父类中静态属性声明初始化,然后再执行静态初始化块。为静态属性在方法区静态数据区开辟空间,若是声明初始化,则赋予初始值,否则默认初始化(double,float为0.0,int为0,boolean 为false,引用类型为null),并且父类和该静态属性关联
  3. 加载子类到内存中
  4. 执行子类中静态属性声明初始,静态初始化块
    5.为父类私有属性(不会被子类继承的属性)在堆中开辟空间(不在子类对象空间中)并初始化
    6.创建子类对象,继承父类public,protected,默认(子类必须和父类在同个包下)修饰的属性和方法,并为默认初始化属性
    7.先执行父类构造块然后再构造方法为父类中属性(包括被继承了和没有被继承)初始化
    8.先执行子类的构造块然后在执行构造方法为子类属性进行初始化
    注:不管是否显示用super调用父类构造方法还是隐藏系统调用构造方法(除非父类构造方法私有了)都会初始化父类的属性。执行顺序:父类静态属性声明初始化—->父类静态构造块—->子类静态属性声明初始化—->子类静态构造块—->父类构造块—->父类构造方法—–>子类构造块—->子类构造方法。其中声明式初始化和构造块初始化之间的顺序是按照他们之间的顺序决定的,其实他们的初始化都放在构造方法里前面的

    首先把子类中用this调用的所有的构造方法压栈,然后再把父类的构造方法压栈,通过this可以调用多个构造方法初始化属性,但是对象只有一个,这说明构造方法不是创建对象的,用new系统来创建对象的。构造方法也是new调用的当父类的属性为private(不能被继承)首先在堆中某片空间开辟空间,(若此属性都可被继承则直接创建子类对象,不需要再为此属性在堆中某片区域开辟空间
    对象初始化过程:父类Person子类Teacher
    子类和父类初始化时,子类和父类构造方法压栈和退栈的过程]![这里写图片描述
    注:创建一个对象时,可能调用多个构造方法(父类和子类的构造方法),通过this和super实现多个构造方法,子类的构造方法先压入栈底,父类压入栈底,然后父类构造方法弹出,子类构造方法弹出
    封装类(jdk1.5以后引进)
    自动拆箱和自动装箱
    Integer I1 = new Integer(2);
    Int I = i1; i1自动会调用intValue方法转换成int类型
    Integer i2= 3; 3会自动封装成Integer类型

基本类型存放的是数,是关键字
封装类存放的是地址,是java类库中的类,该类是final修饰的,不可被继承,该类也是一个不变的类
封装类是final不可被继承,该类只有一个属性和基本类型数相同,类中的属性和方法都是一个final 和staic修饰
重写了toString 和equals方法
从String类型转成int类型,该String类型必须是数字
Integer i =Integer.valeOf(“123”).intValue() int i= Integer.parseInt(“123”);`

equals重写
该方法是超类Object中的方法,所以所有的类都有此方法
File,Date,String,封装类重写了equals方法,若不重写则两者比较的就是hashCode,当两个基本类型的值相等时则返回true,但是两个相同引用类型指向不同的对象,若不重写equals则比较的是两个对象的hashCode内存地址,固然不等返回false
重写equals方法:

“`
public boolean equals(Object obj) {
if(obj == null)
return false;
//this为当前调用equals方法的对象的引用,obj为比较对象的引用。他们指向同一个对象则直接返回true
if(this == obj)
return true;
//如果this和obj不是同一个类型则直接返回false
if(this.getClass() != obj.getClass())
return false;
Student s = (Student)obj;
if(this.name == null){
if(s.name != null)
return flase;
}else{
if(!this.name.equals(s.name))
return false;
}
if(this.age != s.age)
return false;

 return true;

}
toString重写
Object对象的toString方法实现是:returngetClass()+”@”+Integer.toHexString(hashCode())
重写了toString方法有String,封装类,集合(List,Set,Map),Exception

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值