
【百日精通JAVA | 第三篇】多态
子类方法在重写父类的方法是,一般必须与父类方法原型一致:返回值类型 方法名 (参数列表)要完全一致 被重写的方法返回值类型可以不同,但是必须具有父子类型的。如果父类中已经有一个方法了,子类中又有方法名相同的方法,此时父类中的方法会被覆盖,这种情况叫重写/覆盖。animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换。当类中,方法名和参数名都相同时,我们称之为重写,当只有方法名相
目录
一、多态实现的条件:
1.必须在继承体系下
2.子类必须要对父类中方法进行重写
3.通过父类的引用调用重写的方法。
多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。
如果父类中已经有一个方法了,子类中又有方法名相同的方法,此时父类中的方法会被覆盖,这种情况叫重写/覆盖。
重写叫做override
哪些方法不能被重写?
1.被private修饰的方法
2.被static修饰的方法
3.子类的访问修饰限定符一定要大于等于父类的访问限定符修饰。
4.被final修饰的方法
协变类型
当类中,方法名和参数名都相同时,我们称之为重写,当只有方法名相同时,我们称之为重载
方法重写规则:
子类方法在重写父类的方法是,一般必须与父类方法原型一致:返回值类型 方法名 (参数列表)要完全一致 被重写的方法返回值类型可以不同,但是必须具有父子类型的
重载和重写的区别?
二、向上转型和向下转型
向上转型
其实就一句话,通过子类指向父类对象
实际是创建一个子类对象,将其当成父类对象来使用
语法格式: 父类类型 对象名 = new 子类类型()
通过animal的引用无法调用子类的方法,从小范围到大范围的转换。
原因:
类型为animal此时调用时,只能调用父类自己的。
animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换。
向上转型的时机:
1.直接赋值
2.传参
3.返回值
向下转型
向下转型指的是 把父类的引用转换为子类的引用,从而访问子类特有的方法和属性。
前提: 向下转型前,该父类引用必须实际指向的是一个子类对象,否则会导致 ClassCastException报错
。
三、向上转型 vs 向下转型
父类的引用也可以接受子类的对象
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("吃骨头");
}
public void kanJia()
{
System.out.println("看家");
}
}
class Pig extends Animal
{
public void eat()
{
System.out.println("饲料");
}
public void gongdi()
{
System.out.println("拱地");
}
}
class Test
{
public static void main(String[] args) {
Animal c = new Cat(); //我们称之为一个对象具备多种形态
//既是猫类型又是动物类型
c.eat();
}
}
提高了程序的扩展性。
四、多态的性质
多态体现:
父类的引用指向了自己的子类对象
弗雷德引用也可以接受自己子类的对象
多态的前提:
必须是类与类之间有关系,要么继承,要么实现
多态的好处:
多态的出现大大提高了程序的扩展性。
多态的弊端:
只能使用父类的引用访问父类中的成员
五、多态成员特点(面试题)
成员函数的特点
在编译时期,参阅引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有编译失败。
在运行时期,参与对象所属类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
成员变量的特点
无论编译和运行,都参考左边
在多态中,静态成员函数的特点:
无论编译还是运行,都参考左边。
六、项目联系—多态主板示例、扩展示例
interface PCI
{
public void open();
public void close();
}
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void usePCI(PCI p)
{
if(p!=null)
{
p.open();
p.close();
}
}
}
class NetCard implements PCI
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}
public class DuoTaiDemo5 {
public static void main(String[] args) {
MainBoard mb = new MainBoard();
mb.run();
PCI c = new NetCard();
mb.usePCI(c);
}
}
七、练习问题:
为什么先要让类实现这些接口,才可以向上转型
PCI c = new NetCard();
mb.usePCI(c);
只有父类才能实例化子类,如果不先进行继承,那么没办法进行实例化

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。
更多推荐
所有评论(0)