在学习继承后,很多同学会混淆:继承后重载,重写和多态的问题,我就写了一个小程序对下面对几个事情进行下解释。

我建议不理解或则有疑惑的地方,可以自己写个类测试一下就会明白其中的含义。

有些图由于csdn网站的原因,一直显示服务器存在错误,我明天再次上传。

1.首先大家需要先理解重载和重写对定义。

我简单对介绍一下哈,重载就是发生在一个类中,同名函数但是不同参数的多个函数的称呼。而重写就是发生在继承之后,子类重写了父类的一些函数,子类可能因为某些原因认为父类函数过于抽象等原因,进行重写。

二者的区别如下:

下面的例子可以很好的解释我刚的话

参考:https://www.quora.com/What-is-the-difference-between-overload-and-override

2. 用代码来解释一些问题

2.1对继承后,构造函数的理解

如果父类的变量是public修饰时,会被子类继承,那么子类的构造函数的写法就要注意,因为要取决于父类的写法。

2.1.1

先简单的写个父类:都是public修饰,并且只有一个有参的构造函数。

public class Dog {public String name;public Dog(String name){this.name = name;      }
//只有一个代参的构造函数时public Dog(String name){this.name = name;}
}

子类对其进行继承后,对几种构造函数的解释。

package helloword;public class hund extends Dog{public int size;//对构造函数的解释//空参数---会报错,因为hund继承了Dog的name,因此它的构造函数一定是有参数的,public hund(){}// 当构造函数只有一个String是可以的,那么默认,在使用的时候,hund中定义的size就是0,不可以是别的值public hund(String name) {//调用Dog的构造函数super(name);}//错误,没有name的定义public hund(int size){this.size = size;}//正确public hund(String name,int size){super(name);this.size = size;}
}

测试:

 public static void main(String args[]){hund h1 = new hund(); // 报错hund h2 = new hund("dog"); // name = dog ;size = 0;hund h3 = new hund(2); //报错hund h4 = new hund("luckly",2);  name = luckly size = 2}

也就是说使用hund 的实例的时候,必须有name的传参,但是这主要取决于父类Dog的构造函数,只有一个带参数的name

2.1.2

但是如果Dog的构造函数如下,添加一个无参构造函数时,结果就不同。

package helloword;public class Dog {public String name;private double price;public Dog(){}public Dog(String name){this.name = name;}public void eat(){System.out.print("eat food");}public void drink(){System.out.print("drink water");}
}

hund类如下,则都可以声称和运行。

package helloword;public class hund extends Dog{public int size;//对构造函数的解释public hund(){}// 当构造函数只有一个String是可以的,那么默认,在使用的时候,hund中定义的size就是0,不可以是别的值public hund(String name) {//调用Dog的构造函数super(name);}public hund(int size){this.size = size;}public hund(String name,int size){super(name);this.size = size;}public static void main(String args[]){hund h1 = new hund();System.out.print(h1.size);System.out.print(h1.name);hund h2 = new hund(2);hund h4 = new hund("luckly",2);   }
}

2.1.3 子类对实例优先调用父类对构造函数

父类如下:

package helloword;public class Dog {public String name;private double price;public Dog(){System.out.println("我是父类无参构造函数");}public Dog(String name){this.name = name;System.out.println("我是父类有参构造函数");}
}

子类:

package helloword;public class hund extends Dog{public int size;//对构造函数的解释public hund(){System.out.println("我是子类无参构造函数");}// 当构造函数只有一个String是可以的,那么默认,在使用的时候,hund中定义的size就是0,不可以是别的值public hund(String name) {//调用Dog的构造函数super(name);System.out.println("我是子类有参name构造函数");}public hund(int size){this.size = size;System.out.println("我是子类有参size构造函数");}public hund(String name,int size){super(name);this.size = size;System.out.println("我是子类有参size+name构造函数");}public static void main(String args[]){hund h1 = new hund();hund h2 = new hund(2);hund h4 = new hund("luckly",2); }
}

测试:

我是父类无参构造函数
我是子类无参构造函数
我是父类无参构造函数
我是子类有参size构造函数
我是父类有参构造函数
我是子类有参size+name构造函数

2.2 重写和重载

2.2.1 普通重写

父类定义了一个函数eat

public class Dog {public String name;public Dog(String name){this.name = name;      }public void eat(){System.out.print("我是父类的eat函数");}
}

子类重写了这个函数:

package helloword;public class hund extends Dog{public int size;public hund(String name,int size){super(name);this.size = size;}public void eat(){System.out.println("我是子类的eat函数");}public static void main(String args[]){hund h4 = new hund("luckly",2); h4.eat();}
}

在h4调用eat函数的时候,观察结果是调用了子类的函数,而不是父类的,输出结果如下:

我是子类的eat函数

结论:通过这里例子可以发现,其实重写就是覆盖了父类的eat函数,但是如果定义的是父类的子类,肯定父类的eat函数还是可以使用的。

2.2.2  重载和重写

当我们把子类的eat函数,添加一个int的参数时,调用eat(),就是调用父类的eat()了,而调用eat(2)就是调用子类的eat(int temp)函数

父类:

public class Dog {public String name;public Dog(String name){this.name = name;      }public void eat(){System.out.println("我是父类的eat函数");}
}

子类;

public class hund extends Dog{public int size;public hund(String name,int size){super(name);this.size = size;}public void eat(int temp){System.out.println("我是子类的eat函数:我吃了"+temp+"食物");}public static void main(String args[]){hund h4 = new hund("luckly",2); h4.eat();h4.eat(2);}
}

结果:

我是父类的eat函数

我是子类的eat函数:我吃了2食物

结论:其实本质上讲,子类继承了父类的eat(),但是写了一个eat(int temp)也就是带参数的函数,那么这里的eat()就不是重写了,而是重载了。所以当使用h4.eat()的时候,调用的其实是父类的eat(),而使用h4.eat(2)的时候,就是使用子类自己定义的函数。

其实子类也函数在运行的时候可以理解成如下的形式,而eat()是父类给它的

public class hund extends Dog{public int size;public String name;public hund(String name,int size){super(name);//这里的super(name)就是调用父类public Dog(String name)函数,这里没法加入this.size = size;}public void eat(){System.out.println("我是父类的eat函数");}public void eat(int temp){System.out.println("我是子类的eat函数:我吃了"+temp+"食物");}public static void main(String args[]){hund h4 = new hund("luckly",2);   h4.eat();h4.eat(2);}
}

2.3. 多态

2.3.1 普通多态

父类:

public class Dog {public String name;public Dog(String name){this.name = name;      }public void eat(){System.out.println("我是父类的eat函数");}public void drink(){System.out.println("我是子类的drink函数");}
}

子类:

package helloword;public class hund extends Dog{public int size;public hund(String name,int size){super(name);this.size = size;}// drink函数重写public void drink(){System.out.println("我是子类的drink函数");}// eat函数重载public void eat(int temp){System.out.println("我是子类的eat函数:我吃了"+temp+"食物");}public static void main(String args[]){Dog h4 = new hund("luckly",2);    h4.eat();h4.drink();}
}

结果:

我是父类的eat函数

我是子类的drink函数

但是如果使用下面的语句,会报错:

h4.eat(2);

结论:eat是重载的,因此调用的肯定是父类的eat函数,drink是重写的,调用的肯定是子类重写之后的函数

指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。

3. 经典案例分析

下面来看一个经典的案例

public class A {public String show(D obj) {return ("A and D");}public String show(A obj) {return ("A and A");} }public class B extends A{public String show(B obj){return ("B and B");}public String show(A obj){return ("B and A");}
}public class C extends B{}public class D extends B{}public class Test {public static void main(String[] args) {A a1 = new A();A a2 = new B();B b = new B();C c = new C();D d = new D();System.out.println("1--" + a1.show(b));System.out.println("2--" + a1.show(c));System.out.println("3--" + a1.show(d));System.out.println("4--" + a2.show(b));System.out.println("5--" + a2.show(c));System.out.println("6--" + a2.show(d));System.out.println("7--" + b.show(b));System.out.println("8--" + b.show(c));System.out.println("9--" + b.show(d));      }
}

输出结果:

1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D

解释:

其实在继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

首先解释下第二个,a1.show(c),为什么是 A-A

因为根据优先级,会先找A类的show(C),但是函数不存在,而A类的super函数是object,所以第二个super.show(C)也是没有的。然后就是看第三个,this.show((super)C),因为C继承B,B继承A,因此AB都是C的父类。因此就调用A类的函数:public String show(A obj)。

下面的都同理!!

参考:https://www.cnblogs.com/chenssy/p/3372798.html

「java」重载重写多态相关推荐

  1. 「Java」基于Mirai的qq机器人开发踩坑笔记(其一)

    目录 0. 前置操作 I. 安装MCL II. MCL自动登录配置 III. 安装IDEA插件 1. 新建Mirai项目 2. 编写主类 3. 添加外部依赖 4. IDEA运行 5. 插件打包 6. ...

  2. android string拼接字符串_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...

    Java基础之字符串操作--String 字符串 什么是字符串?如果直接按照字面意思来理解就是多个字符连接起来组合成的字符序列.为了更好的理解以上的理论,我们先来解释下字符序列,字符序列:把多个字符按 ...

  3. 「Java」基于Mirai的qq机器人开发踩坑笔记(其二)

    目录 0. 配置机器人 1. onLoad方法 2. onEnable方法 3. 消息属性 4. 消息监听 I. 好友消息 II. 群聊消息 III. 无差别消息 5. 发送消息 I. 文本消息 II ...

  4. java 同步解决不安全类_「JAVA」Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好...

    线程不安全 线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来:示例代码如下: public class ImplementsDemo { public static void ...

  5. java 接口 抽象类 继承 重载 重写 多态

    4.1 抽象类 在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的. 同时,抽象类体现了数据抽象的思想,是实现多态的一种机制.它定义了一组抽象的方法, ...

  6. 「Java」- 八大排序

    目录 前言 1.冒泡排序 2.选择排序 3.插入排序 4.希尔排序 5.堆排序 6.快速排序 7.归并排序 8.计数排序 前言 由于本章介绍的大多数排序都需要用到数组两个元素之间进行交换操作 , 所以 ...

  7. java接口多态的变量能_「JAVA」多态的灵魂,面向接口的程序设计,这才是你该懂得的接口(interface)...

    Java面向对象之接口--interface 什么是接口 一般计算机中的接口分为硬件接口和软件接口. 硬件接口:是指两个硬件设备之间的连接方式,既包括物理上的接口,还包括逻辑上的数据传送协议. 软件接 ...

  8. java借口不同程序_「JAVA」多态的灵魂,面向接口的程序设计,这才是你该懂得的接口(interface)...

    Java面向对象之接口--interface 什么是接口 一般计算机中的接口分为硬件接口和软件接口.硬件接口:是指两个硬件设备之间的连接方式,既包括物理上的接口,还包括逻辑上的数据传送协议. 软件接口 ...

  9. 重载 重写 多态区别

    override是重写(覆盖)了一个方法,以实现不同的功能.一般是用于子类在继承父类时,重写(重新实现)父类中的方法. 重写(覆盖)的规则: 1.重写方法的参数列表必须完全与被重写的方法的相同,否则不 ...

最新文章

  1. 信号与系统参考书推荐
  2. mysql探活_MYSQL探索
  3. java负数右移_Java中负数的右移
  4. Python OS和shutil模块的常见方法
  5. 机房系统(二)——【数据设定 注册 】
  6. php框架所用到的核心概念,【PHP】PHP现代框架代表-Laravel框架核心技术特性
  7. android注销广播接收器,使用广播接收器 - chuiyuan的个人页面 - OSCHINA - 中文开源技术交流社区...
  8. C++编程练习:2-华氏度转摄氏度
  9. mysql 判断质数_质数(素数)判断算法总结
  10. Java实现 蓝桥杯 算法提高 求arccos值
  11. linux中ll排序命令,ll命令
  12. 什么是Banner图?
  13. 怎样制作传奇私服服务器,新手传奇gm必须学会如何制作传奇私服小地图
  14. 安装MySQL绿色版本,不用装软件、不用装软件、不用装软件
  15. java问卷导入excel,将Excel数据直接上传到问卷星
  16. tensorflow中tf.nn.xw_plus_b
  17. MySQL备份(一)增量
  18. Hadoop:MapReduce编程之统计每个订单价格最高的商品信息
  19. 常见的HTT相应状态码
  20. 于我而言,大早上的好消息——JetBrains Fleet来了

热门文章

  1. oppo A37T刷机 ROOT 以及无信号解决办法
  2. mybatis 多条件查询、in查询
  3. 计算机制造属于连续性生产,生产类型
  4. Mybatis-plus 根据条件多个动态or进行嵌套查询
  5. 手机连过的WIFI密码忘了怎么办?
  6. 没有如愿的人生,只有幸福的生活
  7. TCP/IP协议就是这个玩意(不看也不影响拿到50K!但是程序员应该知道这些)持续更新中
  8. 流氓并不可怕,就怕流氓有文化 -- 这是一个知识改变命运的例子
  9. 【Pandas-1】十分钟入门Pandas (上)
  10. 无偿分享 简单易用 贝茨训练法 调节睫状肌 近视恢复训练