方法重写和多态

发布时间 2023-03-22 21:11:07作者: hhya_yyds

1、方法重写

1.1、意义

当子类继承父类方法,但是父类的方法功能无法满足子类的需求,那就需要在子类重新定义父类的方法,加入子类需要的内容,这种就是方法重写

1.2、方法重写或方法的覆盖(overriding)

	1)子类对所继承父类相同方法的一种更改,这个更改需要遵循格式按照父类的格式,访问权限,抛出异常等等,都在父类方法控制范围内,内部具体实现可以实现不同的效果。
    2)重写时,可以用super.方法的方式来保留父类的方法
    3)构造方法由于类名不同,所以不能被继承,也就不能被重写
    4)方法重写的前提是:必须要存在继承的关系。
备注:
    String字符串的equals方法就是最明显的重写,toString()也是
    使用的注解:@override,存在继承关系,可以直接写要重新方法名,自动会带出重写的方法,注意,如果加了注解,代表必须是重写方法

2、方法重写的规则

1)方法重写时,方法名与形参列表必须一致。 
2)方法重写时,子类的返回值类型相同或者是其子类,即必须要小于或者等于父类的返回值类型。
3)方法重写时,子类的权限修饰符不能严于父类,即要大于或者等于父类的权限修饰符。  
4)方法重写时,父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法
5)方法重写时,子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
6)方法重写时,父类的私有方法不能被子类覆盖
7)方法重写时,子类抛出的异常类型要小于或者等于父类抛出的异常类型。

3、方法重载和方法重写的异同

比较项   位置   方法名   参数列表  返回值        修饰符
重写     子类   相同    相同      相同或者子类   不能严于父类
重载     同类   相同    不同      无关          无关

4、Object类

所有类的父类,如果没有使用extends关键字指定基类,那默认是继承object类

object类经常被重写的方法
    toString(); 返回当前对象本身的有关信息,按字符串对象返回
    equals();   比较两个对象是否是同一个对象,是则返回true

重点关注equals方法和toString方法的重写

Object的equals方法
    比较的是两个对象是不是同一个对象,是则返回true
操作符 ==
    对于简单数据类型,比较的是值,如果是引用内容,两者比较的是是否为同一个对象

由此看出
    object的equals跟 == 的效果是一样的
    当有特殊需求时候,如认为属性值相同即为同一个对象,那就要重写equals方法
        平时使用过String类的equals方法,那这个就是重写过equals方法的

5、多态

没使用多态的弊端:
    频繁修改代码,代码的扩展性、可维护性差
        同一个方法,可能需要针对不同的类型参数,重复定义

定义:
    同一个行为,具有多个不同形式的表现或者能力

条件:
    三个必要条件:
        继承--存在继承关系
        重写--子类重写父类的方法(通过父类调用子类的同名方法)
        父类引用对象指向子类的实例(对象)

向上转型:
    父类的引用指向子类的实例,类型自动转换
    语法:
        父类 对象名 = new 子类对象();
向下转型:
    将一个指向子类对象的父类,强转为子类对象
    语法:
        子类 对象名 = (子类)父类的引用变量
    注意:
        向下强转时,必须是转换为真实的子类类型,否则会出现转换异常
        使用instanceof关键字,判断是否是该子类创建的实例

实现多态的两种形式:
    1)父类作为方法形式参数
    2)父类作为方法的返回值

父类指向子类对象时:
    注意:
        1)通过父类引用变量调用的方法是子类覆盖的方法
        2)通过父类引用变量调用的方法是子类未覆盖的,调用的是从父类继承的旧方法
        3)通过父类引用变量无法调用子类特有的方法(父类没有该方法,所以调用不到)
        4)属性也类似

子类引用指向自身对象时:
    注意:
        1)子类引用变量调用的方法是子类覆盖的方法
        2)子类引用变量调用的方法是未覆盖的,实际调用的是从父类继承的旧方法
        3)子类引用变量可以调用子类特有的方法
        4)属性也类似