Java多态
多态
☀️1.多态的定义☀️
多态(polymorphism)是面向对象编程(OOP:object oriented programming)的一个重要特征,顾名思义为多种形态,详细解释为一个接口,多种实现,即方法的实现应取决于调用该方法的对象。
通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
☀️2.多态的组成条件☀️
多态的组成条件分为3部分,分别为继承,方法重写与父类引用指向子类对象,下面,我们一个个看。
❄️2.1继承❄️
之前写过继承,可以看看Java继承
这篇文章,继承就不在多说了。
❄️2.2方法重写❄️
⛄️2.21方法重写的定义⛄️
子类通过重写可以隐藏自己继承的方法,即如果子类可以继承父类的某个方法,那么子类就有权利重写这个方法,重写时,方法的返回值和形参都不能改变,就是外壳不能变, 里面的核心代码重写,即重写的这个方法的名字、参数个数、参数的类型要和父类的方法完全相同。子类这样定义的方法称作子类重写的方法。
⛄️2.22方法重写的目的⛄️
可以隐藏从父类继承的方法,子类通过方法的重写可以把父类的状态和行为改变为自身的状态和行为,如果非要用父类的方法可以使用关键字super。
⛄️2.23方法重写的注意事项⛄️
1、参数列表必须完全与被重写的方法完全相同。
2、返回类型也必须要和被重写的方法完全相同。
3、访问权限不能比父类中被重写方法的访问权限低,
4、声明为final的方法不能被重写,
5、声明为static的方法也不能被重写,但是可以被再次声明。
6、如果子类和父类是在同一个包,那么子类可以重写父类的所有的方法,
7、如果子类和父类不在同一个包,那么子类只能重写父类的声明为public和protected的方法
8、构造方法也不能被重写。
⛄️2.24方法重载的定义⛄️
一个类中可以有很多个方法具有相同的名字,但这些方法的参数必须不同,返回类型可以相同也可以不同。
⛄️2.25方法重载的注意事项⛄️
方法的返回类型和参数的名字不参与比较,也就是说,如果两个方法的名字相同,即使返回类型不同,也必须保证参数不同,不然就不是方法重载。
参数不同包括:
1、参数的个数不同
2、参数的个数相同,但是参数列表中对应的某个参数的类型不同
⛄️2.26方法重写与方法重载的区别⛄️
1.方法重载(overload)和方法重写(overriding)是java中的两种多态,重写是父类和子类之间的一种多态的表现,而重载是一个类的多态表现。
2.方法重载能改变返回值类型。
❄️2.3父类引用指向子类对象❄️
举个例子吧
class father
{
public void show()
{
System.out.println("father");
}
}//父类
class son extends father
{
public void show()
{
System.out.println("son");
}
}//子类继承了父类并且进行了方法重写
//已经完成了多态的前两步了
class test
{
public static void main(String[] args)
{
father new1 = new son();//父类引用指向子类对象
new1.show();
}
}
其中test类中father new1 = new son()就是父类引用指向子类对象
最后输出的结果为
son
为什么会输出这个结果呢
我们继续往下面看。
☀️3.相关注意事项☀️
❄️3.1成员方法❄️
class father
{
public void show()
{
System.out.println("father");
}
}//父类
class son extends father
{
public void show()
{
System.out.println("son");
}
}//子类继承了父类并且进行了方法重写
//已经完成了多态的前两步了
class test
{
public static void main(String[] args)
{
father new1 = new son();//父类引用指向子类对象
new1.show();
}
}
这个和上面的一样
最后输出
son
❄️3.2成员变量❄️
class father
{
int age =10;
}
class son extends father
{
int age = 12;
}
class test1{
public static void main(String[] args)
{
father new1 = new son();
System.out.println(new1.age);
}
}
最后输出的结果为
10
怎么和第一个不一样呢,按照第一个的规律不应该输出
12吗
别急,我们再继续看下一个
❄️3.3静态方法❄️
class father{
public static void show()
{
System.out.println("父类的静态方法");
}
}
class son extends father{
public static void show()
{
System.out.println("子类的静态方法");
}
}
class test{
public static void main(String[] args)
{
father new1 = new son();
new1.show();
}
}
最后输出
父类的静态方法
又和第一个的规律不一样了
❄️3.4结论❄️
成员变量
编译看左边(父类),运行看左边(父类)
成员方法
编译看左边(父类),运行看右边(子类)
静态方法
编译看左边(父类),运行看右边(父类)
☀️4.多态的作用☀️
1不必编写每一子类的功能调用,可以直接把不同子类当父类看,屏蔽子类间的差异,提高代码的通用率/复用率
2父类引用可以调用不同子类的功能,提高了代码的扩充性和可维护性
☀️5.多态的好处与不足☀️
好处:隐藏了子类类型,提高了代码的可扩展性。
弊端:只能使用父类的功能,无法使用子类的特有的功能,功能有限制(因为想要实现多态,必须有方法重写,这就意味着,子类有的方法而父类没有,则无法进行编译)
☀️6.向上转型与向下转型☀️
class father{
int age = 10;
}
class son extends father{
int age = 20;
}
class test{
public static void main(String[] args)
{
father new1 = new son();
System.out.println(new1.age)
}
}
这个结果我们都知道
为
10
可是,如果我们想得到子类的age应该怎么做呢
为此,我们特地介绍下面两种概念
❄️6.1向上转型❄️
引用父类指向子类对象就是向上转型
这个没啥说的
在本题中就是这块
father new1 = new son();
❄️6.2向下转型❄️
在讲述向下转型前,我们先想一下这块
int age =10;
int age1 = 10;
我想让age1向下变成short类型应该怎么做
按照以前学过的方法,我们一下子就能想出是强制类型转换
int age = 10;
short age1 = (short)age;
向下转型与向下强制类型转换相似
但有一点不同
向下转型要先进行向上转型
好了
现在知道怎么输出son里面的age了
class father{
int age = 10;
}
class son extends father{
int age = 20;
}
class test{
public static void main(String[] args)
{
father new1 = new son();//向上转型,也可以说引用父类指向子类对象
son new2 = (son)new1;//向下转型
System.out.println(new2.age)
}
}
最后输出来结果
20