Java复习5 继承、多态(向上、向下转型)、组合

5. 继承、多态、组合

5.1 继承

5.1.1 继承的语法
class SubClass extends SuperClass{
...
}
  1. 子类可以继承父类的所有成员,包括被private修饰的成员,子类只是无法访问、不能调用被private修饰的方法罢了。
  2. 子类不能继承父类的构造函数。
  3. 执行子类的构造方法之前,会先调用父类中没有参数的构造方法,其目的是为了要帮助继承自父类的成员做初始化操作。
  4. 子类继承的方法只能操作子类继承和隐藏的成员变量。
  5. 子类重写的方法也能直接操作被子类隐藏的成员变量。
  6. 但子类新增的方法不能直接操作被子类隐藏的成员变量。
5.1.2 成员变量的隐藏和方法的覆盖
  1. 在Java中子类也可以隐藏由父类继承来的成员变量,只要子类中声明的成员变量和父类的成员变量同名,就可以将其隐藏。
  2. 子类对象可以调用从父类继承的方法操作隐藏的成员变量。
  3. 重写的方法既可以继承变量,也可以操作子类新声明的成员变量。如果子类想使用被覆盖的方法,必须使用关键字super。
  4. 实例中,变量被隐藏,方法被覆盖。
  • 覆盖
    1)覆盖是指在子类中定义名称、参数个数与类型均与父类中完全相同的方法,用以重写父类中同名方法的功能。方法头相同,方法体不同。
    2)子类中不能覆盖父类中声明为final或static的方法。
    3)在覆盖时访问权限只能放大或相同,不能缩小。
    4)覆盖方法不能抛出新的异常。(?
5.1.3 super

如果想在子类中使用父类的非私有成员,可以使用super关键字。
super语句必须出现在子类构造方法非注释语句的第一行。

super.变量名;
super.方法名;
5.1.4 final
  • final修饰类,表示该类不能被继承,即该类不能有String等子类。
  • final修饰方法,表示该方法不能被重写。
  • final修饰变量,该变量可以理解为常量,必须赋初值(可在声明时或在类的构造方法中赋值)。

5.2 多态

5.2.1 多态的理解

1.一个类有多个子类,并且这些类都重写了父类的某个方法。即多态存在在三个必要条件是:
继承;重写;父类引用指向子类对象:Parent p = new Child();
2.多态中,不能访问子类的特有成员,只能通过实例化子类对象来访问。
3.为此,介绍多态的两种转型:向上转型和向下转型。向上转型后子类不能调用自己的私有属性和私有方法,只能调用父类属性和重写的父类方法。如果向上转型后想要调用子类的私有属性和方法,可以强制向下转型。
临时问题:子类能调用自己的公有成员吗?

5.2.2 向上转型和向下转型
  • 向上转型的理解:
    1.由子到父,父类的引用指向子类对象,即 Animal a = new Cat();
    2.当有子类对象赋值给一个父类引用时,便是向上转型,多态本身就是向上转型的过程。
    3.格式:父类类型 变量名 = new 子类类型();
  • 向下转型:
    1.由子到父,父类的引用转为子类对象,即Cat c = (Cat)a; (强制类型转换)
    2.一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用转为子类引用,这个过程是向下转型。如果是直接创建父类对象,是无法向下转型的。
    3.格式:子类类型 变量名 = (子类类型) 父类类型的变量;
    例如:Cat c = (Cat)a; //变量a 实际上指向Cat对象
    即新创建了一个Cat类型的对象c指向强制转换类型后的a

注:1.c和a的地址一样。2.关于对象存放在堆还是栈中,对象是存放在堆中 变量名存放在栈中,即如果new出来了一个对象就放在堆里,直接定义的局部变量(Cat c;)就放在栈里,此处对象c放在栈里。3.向下转型是有风险的,必须是继承关系才能转型成功,否则程序运行时就会抛出异常,为了防止这种情况,就要使用instanceof运算符。

“instanceof关键字的作用是判断左边对象是否是右边类(这里有很多人说是对象,所以注意这里是类,并不是对象)的实例(通俗易懂的说就是:子类对象,或者右边类本身的对象)返回的boolean类型,true和false。”

参考内容:链接1链接2链接3

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法,里面是匿名对象
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat,向上转型后才能向下转型
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
        a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

执行以上程序,输出结果为:

吃鱼
抓老鼠
吃骨头
看家
吃鱼
抓老鼠

存疑:多态学习

5.3 组合

在一个新类中创建一个已有类的对象。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值