继承
- 继承的好处:减少代码的冗余,增强可扩展性,为多态的实现提供了前提条件
- classA extends classB
- 继承所有属性与方法,就算这些属性与方法是私有的,也是已经继承了,但是不能直接使用而已
- 一个类可以被多个子类继承,一个类只能有一父类
- 多重继承,直接继承,间接继承
- 所有类都直接或间接地继承于java.lang.Object
JavaBean
- 该类的权限是public,
- 含有一个空参的构造器,且该构造器是public
- 含有相关的属性,若该属性是private,则含该属性对应的set(),get()方法
方法重写
1.在子类继承父类后,如果该方法不符合子类,可以在子类中对父类中的方法进行覆盖
重写的规定:
- 子类中的是重写的方法,父类中的是被重写的方法
- 方法名与形参列表相同
- 子类重写方法的权限修饰符不小于被重写方法
- 被重写方法是private则子类中不能重写该方法,因为该方法不可见,但是是可以调用的
- 返回值类型:
被重写方法的返回值类型为void,则重写方法的返回值类型的只能是void
被重写方法的返回值类型为A类型(引用数据类型),则重写方法的返回值类型的只能是A或A的子类
被重写方法的返回值类型为基本数据类型,则重写方法的返回值类型的只能是相同的基本数据类型 - 子类重写方法抛出的异常类型不大于父类被重写方法抛出的异常
- 子类和父类的同名同参方法要么都是非static的(这时为重写),要么都为static(此时不构成重写,但方法依然成立,因为static方法不可被重写)
super关键字
- super的引入,
方法的重写过程中,被重写方法虽然已不适用于子类的同名重写方法,但是子类的其他方法却还是会用到被重写方法,因此需要区分这两种方法 - 类比this,this的出现是因为方法的形参名与属性相同,无法区分两者的情况下,使用 this.name=name,
- super可以修饰属性,方法
方法可以重写,覆盖,但属性不能,
我们可以在子类的方法或构造器中,通过super.属性或super.方法的形式调用父类的属性与方法,但我们一般会省略super
但在子类中我们如果定义了同名属性,这样我们调用的就是子类的,若想调用父类,则必须加上super - super调用构造器
我们可以在子类的构造器中显式的使用super(形参列表)的方式,调用父类中声明的指定的构造器,但是必须写在首行。
由于 this(形参列表)这种调用本类构造器的方式的存在,在类的构造器中 this或super 只能二选一
在构造器的首行,没有显式的声明this(),或super()时,默认调用super()
子类对象实例化全过程
1.从结果上看,子类继承父类后,就获取了父类中声明的属性或方法,而在创建子类的对象时,在堆空间中,就会加载所有父类声明的属性
2.从过程上说,子类的构造器会直接或间接地调用直接父类的构造器,进而调用间接父类的构造器,直到调用到java.lang.Object类中空参构造器为止。
5. 注意创建子类对象时,虽然调用父类的构造器,但是自始至终,也只会创建一个子类对象
多态性
- 可以理解为事物的多种形态
Person p1=new Man();//父类的引用指向子类的对象(子类的对象赋给父类的引用) - 这个时候我们是无法调用子类(MAN)中特有的方法的,因为我们声明的是一个父类(Person)对象;当调用子父类都声明过的属性与方法时,调用的是子类重写的;
- 编译看左边,执行看右边——在编译期(程序是否通过),只能调用父类中声明的方法,在运行期,我们实际执行的是子类重写的方法
- 多态的使用前提:继承(必须涉及子父类才会有,父类的引用指向子类的对象),重写(必须涉及方法的重写才会有编译看左边,执行看右边)
- 为什么要有多态
多态的存在直观的减少了,不同子类对同一父类的方法的重写,父类根据不同子类对象,动态调用属于子类的该方法。例如,Object类中的wait,equals等方法都是通过多态实现的,对于不同的子类 - 注意,对象的多态性,只适合方法,不适用于属性,也就是说,当子类和父类声明了同名属性,此时调用的是左侧的父类属性
- 总结
正常方法调用:(左侧)声明类 =(右侧)创建对应对象
虚拟方法调用:(左侧)声明父类 = (右侧)创建子类对象,此时父类方法被称为虚拟方法。 - 重载与重写
从编译与运行的角度来看,重载是指允许存在多个同名不同参的不同方法。对重载而言,在方法调用之前,或者说在编译的时候就已经确定了要调用的方法,这成为,“早绑定”或“静态绑定”
而对于多态,由于编译期是无法确定要调用的具体的子类方法,所以只有在运行的时候才能确定需要执行的方法,这称为“晚绑定”或“动态绑定”。
instanceof关键字
- a instanceof A:判断对象a是否为类A的实例
Object类
- Object类是所有JAVA类的根父类
- 如果在类的声明中没有显式的使用extends 关键字指明其父类,则默认父类为Object.
- className.getClass().getSuperclass()——获取直接父类
- 方法:equals(),toString(),getClass()
==
- == 可以用于基本数据据类型和引用数据类型,
- 注意,在使用 == 进行基本数据类型的比较时,只会比较值的大小,类型并不能决定;
char a=10;
double b=10.0;
a==b;//true - 在进行引用数据类型的比较时,比较的是地址值,但首先需判断两者类型是否相同
equals()
- equals()是方法,而非运算符,因此它只能适用于引用数据类型
- Object类定义的equals()方法与== 是一样的,但是在一些类中equals()方法被重写了,不再是比较地址,例如String中比较的是内容
- 那如何在自定义类中重写equals()
toString()
- 当我们输出一个对象的引用时实际上就是调用当前对象的toString()方法
System.out.println(a);
System.out.println(a.toString());//这两种写法的结果相同 - Object类中toString()方法
return getClass().getName() + “@” + Integer.toHexString(hashCode());
4.像String,Date,File,包装类都重写了Object类中的toString()方法,使得在调用对象的toString()方法时,返回“实体内容”。