重写
定义:重写是子类对父类的允许访问的方法的实过程进行重现新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
class Member { //普通会员类
String username; //名字
List<String> list=new ArrayList();
public void setUserName(String username){
this.username=username;
}
public void watchPower(){ //普通会员可以看以看的视屏的清晰度
list.add("流畅");
list.add("标清");
list.add("高清");
}
public void showPower(){
System.out.print("用户"+username+"可以看:");
for(String i:list){
System.out.print(i+" ");
}
}
}
class SuperMember extends Member{
public void watchPower() { //重写
list.add("流畅");
list.add("标清");
list.add("高清");
list.add("超清");
}
}
上面是一个看视屏的例子,普通用户可以看流畅、标清、高清,超级用户还可以看超清,重写了watchPower 这个方法。
重写规则: 两同两小,一大原则:
方法名相同,参数类型相同。
子类返回类型小于等于父类返回类型,
子类抛出异常小于父类方法抛出异常,
子类访问权限大于等于父类访问权限。
声明为final的方法不能被重写。
声明为static的方法不能被重写,但是能够被再次声明。
子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
构造方法不能被重写。
如果不能继承一个方法,则不能重写这个方法。
重载
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
重写与重载之间的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 只能返回等于或比原来范围更小的类的对象 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
总结
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
- (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
- (2)方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样或者比父类方法返回类型小的方法,就称为重写(Overriding)。
- (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
多态
多态是同一个行为具有的多个不同表现形式或形态的能力。
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
博主个人认为,多态分为两种,一种赋值多态,一种传参多态。
赋值多态;就是指父类的引用指向了子类,当父类的引用变量执行同一个函数时,执行不同的操作。
传参多态:就是指扩大一个函数的入口范围,使某个顶级父类作为这个函数的参数类型,从而可以让每一个子类对象都可以传参进来。
下面,先给大家用代码分别表现一下赋值多态和传参多态。
赋值多态:
定义一个usb接口,提供给接口方法。
public interface UsbInter {
public void transferSingal();
public void transferFile();
public void charging();
}
定义一个电脑Usb的类把功能加进来
public class Usb implements UsbInter{
public void transferSingal(){
System.out.println("接收信号入口");
}
public void transferFile(){
System.out.println("接收文件");
}
public void charging(){
System.out.println("充电");
}
}
鼠标实现了这个接口,它只有传输信号的功能
public class Mouse implements UsbInter{
public void transferSingal() {
System.out.println("输出信号");
}
public void transferFile() {
System.out.println("无此功能");
}
public void charging() {
System.out.println("无此功能");
}
}
u盘实现了这个接口,他只有传文件的功能
public class UsbDrive implements UsbInter{
public void transferSingal() {
System.out.println("无此功能");
}
public void transferFile() {
System.out.println("传输文件");
}
public void charging() {
System.out.println("无此功能");
}
}
手机实现,它出了传输信号,传文件,还有可以被充电的功能。
public class Phone implements UsbInter{
public void transferSingal() {
// TODO Auto-generated method stub
System.err.println("传输信号");
}
public void transferFile() {
System.out.println("传输文件");
}
public void charging() {
System.out.println("正在充电");
}
}
测试类
public class Test {
public static void main(String[] args) {
UsbInter uInter=new Usb();
UsbInter uInter2=new Mouse();
UsbInter uInter3=new Phone();
UsbInter uInter4=new UsbDrive();
uInter.charging();
uInter2.charging();
uInter3.charging();
uInter4.charging();
}
}
结果
充电
无此功能
正在充电
无此功能
可以看到同一种类型的引用变量,由于指向了不同的子类类型之后,执行同一个函数时,进行了不同的操作。
传参多态:
创建用户类
public class User {
private String name;
private String passWord;
private int score;
public User(){}
public User(String name,String pass0) {
this.name=name;
this.passWord=passWord;
}
public static final void alterPassWord(User user,String pass0) {
user.passWord=pass0;
System.out.println(user.name+" 您好,您已经成功修改密码");
}
}
创建Student类
public class Student extends User{
public Student(String name,String PassWord) {
super(name, PassWord);
}
}
创建教师类
public class Teacher extends User {
public Teacher(String name,String PassWord) {
super(name, PassWord);
}
}
创建测试类
public class Test {
public static void main(String[] args) {
Student s1=new Student("lxt","1234ds");
Teacher t1=new Teacher("sjc", "dsfa");
User.alterPassWord(s1, "queen");
User.alterPassWord(t1, "kingdom");
}
}
可以看到Student,和Teacher是无法自己更改密码的,必须user类调用。并且可以看到,alterPassWord方法并没有重载,而是传了一个User类型的参数,这样当引用变量为,User或者Student或者Teacher时,都可以使用,从而做到了多态。
结果:
lxt 您好,您已经成功修改密码
sjc 您好,您已经成功修改密码