1.继承的概念:
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,
或子类从父类继承方法,使得子类具有父类相同的行为。
当然我们可以从生活中的例子来理解继承,就像儿子继承父亲的家业还是什么,或者说徒弟继承师傅的衣钵.
生活中的继承:
1.1 继承的作用
在java中继承的作用简而言之就是: 完成共性的抽取,实现代码复用,更重要的是有了继承才有了方法的覆盖和多态机制
它允许程序员在保持原有类特性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。
继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程.
在Java中被继承的类叫做父类(超类)或者是基类,而继承的类叫做子类或者是派生类
如果一个类不继承任何类默认继承Object类,Object类是所有类的父类,每个类都直接或间接继承Object类,并且java只支持单继承,并不支持多继承,但是接口却支持多继承.
什么可以继承:
除了静态的不支持继承,构造方法不支持继承,final修饰的不支持继承,私有的不支持继承以外,其他的都可以继承
如图,我们就说B继承A, B为子类,A为父类
1.2子类和父类中成员变量和方法的调用
在当前情况,可以通过子类引用直接访问父类的实例,因为B继承了A
那子类也可以有自己特有的特有属性,并且可以与父类成员变量相同,但是如果实例方法的方法名,形参列表,方法修饰符完全相同,那就构成方法的重载(重写)了.
与方法重载的不同,方法重载在同一类中,并且只要求方法名相同,而形参列表不同.
而方法重写发生在具有继承关系的子类中
需要注意的是,子类重写父类方法的时,重写方法不能有比父类更严格的权限访问
当前子类doSome()方法的权限是default低于public ,所以子类的doSome()必须要public 修饰
1.2.1子类实例变量与父类重名
当实例变量与局部变量重名时,我们用this表示当前对象的引用,来表示实例变量,
同理当子类实例变量与父类实例变量重名时我们使用super来访问父类中的实例变量
上面是访问本类中的name,下面是访问父类中的name
this与super
this与super有很多的相似之处
this
1.在局部变量与实例变量冲突时,this表示当前对象的引用,使用this表示实例变量
2.在构造方法中调用其他的的构造方法,并且只能出现在调用构造方法中的第一行,并且只能出现一次.
super
1.子类与父类的实例变量名冲突时,使用super访问父类中的实例方法和实例变量,与this不同
,super只是一个关键字,并不是引用
2.在进行创建子类对象是,必须先对父类对象进行初始化,然后才对子类对象进行初始化
那就需要调用父类中的构造方法,这时可以使用super调用父类中的构造方法,并且跟this调用构造方法一样,只能出现在第一行,也就说在调用构造方法时,this和super不能同时出现
注意:在访问实例变量时可以使用this,this可以访问从父类继承的实例变量和子类特有的实例变量,但是当父类与子类的实例变量重名时,this只能访问到子类的实例变量,此时只能用super访问父类的实例.
上图是this和supe在访问实例变量的范围
1.2 继承中的执行顺序
在实例化一个子类对象时,会首先执行父类中的静态代码块,然后是子类的静态代码块,并且静态方法是在类加载的时候执行的,并且只执行一次,然后是父类的实例,在到父类的构造方法,最后是子类的实例,和构造方法.
public class Test {
public static void main(String[] args) {
B b = new B();
}
}
class A{
String name;
int age;
static {
System.out.println("父类静态块");
}
{
System.out.println("父类实例代码块");
}
public A() {
System.out.println("父类构造");
}
public void doSome(){
System.out.println("父类方法");
}
}
class B extends A{
String name;
static {
System.out.println("子类静态块");
}
{
System.out.println("子类实例块");
}
public B() {
System.out.println("子类构造");
}
public void method(){
System.out.println(name);
System.out.println(super.name);
System.out.println("子类方法");
super.doSome();
}
public void doSome(){
System.out.println("子类重写");
}
}
这是以上代码的执行结果,可以看出执行顺序就是先父后子,先静态后实例,最后构造
2.多态
通俗来讲就是一种事物的不同形态,例如H₂O在液态的时候是水,气态的时候是水蒸气,固态的时候是冰.
在java中多态就是父类型引用指向子类型对象
2.1 类型转换
向上转型(自动类型转换) :子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象. (小转大)
public class Test {
public static void main(String[] args) {
Animal a=new Cat();
}
}
class Animal{
String name;
public void eat(){
System.out.println("动物会吃");
}
}
class Cat extends Animal{
int age;
public void eat(){
System.out.println("猫吃鱼");
}
}
上面就是把Cat转成Animal是向上转型(自动类型转换)
向下转型(强制类型转换): 向下转型是把父类对象转为子类对象
Cat c=(Cat)a
这就是向下转型(强制类型转换)
需要注意的是只有是具备继承关系的才可以进行类型转换,并且都是在子类的基础上进行类型转换的,不可以对父类对象进行转型
上面都是错误的向下转型,是类型准换异常的
为了避免向下转型的错误,在进行向下转型的时候使用instanceof关键字
instanceof
instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
语法格式:
if(变量名 instanceof 类型)
每次在进行向下类型转换是都是用instanceof来进行判断
2.2多态访问实例变量和实例方法
2.2.1访问实例变量
访问实例方法当前是什么类型就访问该类实例对象的变量
简而言之就是编译看左运行也看左
public class Test {
public static void main(String[] args) {
Animal a=new Cat();
System.out.println(a.name);
}
}
class Animal{
String name="动物";
public void eat(){
System.out.println("动物会吃");
}
}
class Cat extends Animal{
int age;
String name="猫";
public void eat(){
System.out.println("猫吃鱼");
}
}
这里打印的结果是动物
2.2.2访问实例方法
简而言之就是编译看左运行看右
此时需要对父类中的方法进行重写(覆盖)
可以看到父类引用,最后执行的是Cat中的eat方法
以上就是本次的全部内容,谢谢大家