type
status
date
slug
summary
tags
category
icon
password
Property
覆写
在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(Override)
在
Person
类中定义了run()
方法:在子类
Student
中,覆写这个run()
方法:Override和Overload不同的是,如果方法签名不同,就是Overload,Overload方法是一个新方法;如果方法签名相同,并且返回值也相同,就是
Override
。注:方法名相同,方法参数相同,但方法返回值不同,也是不同的方法。在Java程序中,出现这种情况,编译器会报错。
加上
@Override
可以让编译器帮助检查是否进行了正确的覆写。希望进行覆写,但是不小心写错了方法签名,编译器会报错,
@Override
不是必需的。一个实际类型为
Student
,引用类型为Person
的变量,调用其run()
方法,调用的是Person
还是Student
的run()
方法?Java的实例方法调用是基于运行时的实际类型的动态调用,而非变量的声明类型。
这个非常重要的特性在面向对象编程中称之为多态 Polymorphic。
多态
多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法。例如:
假设编写的这样一个方法:
它传入的参数类型是
Person
,我们是无法知道传入的参数实际类型究竟是Person
,还是Student
,还是Person
的其他子类,因此,也无法确定调用的是不是Person
类定义的run()
方法。所以,多态的特性就是,运行期才能动态决定调用的子类方法。对某个类型调用某个方法,执行的实际方法可能是某个子类的覆写方法。这种不确定性的方法调用,究竟有什么作用?
假设定义一种收入,需要给它报税,那么先定义一个
Income
类:对于工资收入,可以减去一个基数,那么可以从
Income
派生出SalaryIncome
,并覆写getTax()
:如果享受国务院特殊津贴,那么按照规定,可以全部免税:
现在,要编写一个报税的财务软件,对于一个人的所有收入进行报税,可以这么写:
利用多态,
totalTax()
方法只需要和Income
打交道,它完全不需要知道Salary
和StateCouncilSpecialAllowance
的存在,就可以正确计算出总的税。如果要新增一种稿费收入,只需要从
Income
派生,然后正确覆写getTax()
方法就可以。把新的类型传入totalTax()
,不需要修改任何代码。可见,多态具有一个非常强大的功能,就是允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码。
覆写Object方法
因为所有的
class
最终都继承自Object
,而Object
定义了几个重要的方法:toString()
:把instance输出为String
equals()
:判断两个instance是否逻辑相等
hashCode()
:计算一个instance的哈希值
在必要的情况下,可以覆写
Object
的这几个方法:调用super
在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过
super
:final
final
修饰符有多种作用:final
修饰的方法可以阻止被覆写
final
修饰的class可以阻止被继承
final
修饰的field必须在创建对象时初始化,随后不可修改
继承可以允许子类覆写父类的方法,如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为
final
:如果一个类不希望任何其他类继承自它,可以把这个类本身标记为
final
:对于一个类的实例字段,同样可以用
final
修饰,用final
修饰的字段在初始化后不能被修改:对
final
字段重新赋值会报错:可以在构造方法中初始化final字段: