记得这个问题当初只是在校招的时候才会问题,后来无意中听到同事面试一个社招提到这个问题?引起了我的思考,谈谈想法
1、什么是多态?
某一类事物的多种存在形态。
例如:动物中的猫、狗
猫这个对象对应的类型是猫类型, 猫 x = new 猫();同时猫也属于动物中的一种。也可以把猫称为动物。
动物 x = new 猫() ; //父类型引用指向子类对象。
动物是猫和狗具体事物中抽取出来的父类型,父类型引用指向子类对象。用一句比较通俗的话:同一操作作用于不同的对象,可以产生不同的效果。举个例子:狗和猫都属于动物,但是他们eat方法是不同的。
2、为什么要用多态? 先看段代码
class dog extends Animal{
@Override
public void eat() {
System.out.println("啃骨头");
}
public void watchHouse(){
System.out.println("狗的特有方法看家");
}
}
class cat extends Animal{
@Override
public void eat() {
System.out.println("吃鱼");
}
}
public class duotai1 {
public static void main(String[] args) {
cat cat = new cat();
cat.eat();
dog dog = new dog();
dog.eat();
dog.watchHouse();
宠物店里面才有两种动物,调用eat方法就这样,万一动物搞了上百种怎么办?程序代码太耦合了没有扩展性,我们需要使用一种方法可以增加拓展性。–使用多态
3、能干嘛?
把一类事物的共性抽取出来,然后封装一个方法专门调用各对象中的方法。增加程序扩展性
4、怎么玩
abstract class Animal{
public abstract void eat();
}
class dog extends Animal{
@Override
public void eat() {
System.out.println("啃骨头");
}
public void watchHouse(){
System.out.println("狗的特有方法看家");
}
}
class cat extends Animal{
@Override
public void eat() {
System.out.println("吃鱼");
}
}
public class duotai1 {
public static void main(String[] args) {
/**
* 多态:一个继承了父类对象的多种表现形态
*/
eatFunction(new cat());
eatFunction(new dog());
/***
* 以后在来 猪 猴子 老鼠 大象都不怕了,扩展性得到了提升
* eatFunction(new 猪());
* eatFunction(new 猴子());
*/
}
public static void eatFunction(Animal animal){
animal.eat();
if(animal instanceof dog){ //子类对象的特有方法,也可以进行调用。
dog dog = (dog)animal; //animal向下转,多态(dog-->animal向上提升,animal肯定也可以向下)
dog.watchHouse();
}
//******* 如果以后还有什么额外的方法直接在本方法中实现**********
}
}
5、注意细节
多态的实现前提:必须是类与类之间有联系,要么继承,要么实现。通常还有一个前期叫做覆盖重写。
多态的弊端:虽说提高了程序扩展性,但是只能使用父类中的引用访问父类中的成员。如果要访问子类中的成员,必须向下转型。
6、上面的案列实现的是类的继承,那么接口呢?可以写一个出来么?别偷懒,写不出来就是不会。java需要勤劳。
案列:台式机主机里面为什么要留卡槽,而不是直接焊死,其实就是一种扩展性的考虑。卡槽其实也是有规格的,不是任何一种格式的内存条都可以插入,所以这里其实就是要满足主机中定义的标准接口才可以使用。
interface PCI{
void open();
void close();
}
class MainBoard{
public void run(){
System.out.println("主机跑起来");
}
public void userPCI(PCI pci) {
if(pci!=null){
pci.open();
pci.close();
}
}
}
class NetCard implements PCI{
@Override
public void open() {
System.out.println("netcard open");
}
@Override
public void close() {
System.out.println("netcard close");
}
}
class CachCard implements PCI{
@Override
public void open() {
System.out.println("CachCard open");
}
@Override
public void close() {
System.out.println("CachCard close");
}
}
public class duotaiInteface {
public static void main(String[] args) {
MainBoard mb = new MainBoard();
mb.run();
mb.userPCI(null);
mb.userPCI(new NetCard());
mb.userPCI(new CachCard());
}
}
总结: 这里的MainBoard 可不可以理解为我们项目里面写的controller层,而 PCI 就是service的接口类,同时NetCard 和CachCard 算不算接口实现类呢。所以流程就变成了 controller->inteface->imp(具体实现类)