java学习day14---(多态)

其他方法不能调用构造函数
子类的构造函数会隐式的调用父类的构造函数,必须的
静态方法可以继承,在静态方法中,不能使用supre调用其他方法,因为静态方法只能调用静态的属性和方法

多态(难点、重点)

同一个动作在不同的场合,会产生不同的效果
同一个方法,传递不同的参数,得到不同的结果
用抽象去代替具体

前提:1、继承 2、重写/覆盖
语法:
父类类型 对象名=new 子类类型();
只能调用重写的方法(调用子类别的方法不行)
对象名.重写方法() 调用的是重写的方法
例子:
class a extends b{}
b sc=new a();
sc.重写的方法 调用的是子类的重写方法

语法很简答,要理解多态!
多态不能调用子类的独有方法
解决方法:


 

首先要了解,引用类型转换问题:
class a extends b{}
b x=new a();
向上转型 :创建一个子类对象赋值给父类类型对象名
类似小转大 如:int a=0 ; double b= a;

向下转型:父类类型的变量赋值给子类类型的对象
为什么调用不了子类的独有方法?
因为 x的对象是b类的类型,b类的类型是不会有a类类型的独有方法的,因此调用不了
解决方法就是向下转型
把x从b类类型转成a类类型 强制类型转换符
a y=(a)x;
这样变量y就能调用 a类型的方法了

强制类型转换,会造成精度缺失和精度溢出
同理多态向下转型,会造成类型转换异常:ClassCasException
关键字:instanceof 判断某个变量应用的对象属不属于某种类型
y instanceof b 判断y这个对象名是不是存储的b类型的对象


 

逻辑总结:
多态:1、继承 2、重写 3、向上转型
因为向上转型,使父类对象名存储了一个子类的对象,导致父类对象名不能调用子类的独有方法
然后向下转型,使父类对象名转换成子类对象名,这样子类对象名存储了一个子类对象,这样就
可以调用子类的方法
但是这样有什么意义呢?直接创建子类对象赋值给子类的对象名不行吗?


 

因此需要重写父类的方法,这样在把子类对象存储到父类对象名中时,父类对象名.方法就调用的是子类对象的方法

例子:

public class  A{

     public void fun(){

      System.out.println("说话");

}

}

 

public class B extends A{                  //B继承了A

      public void fun(){                 //重写A类方法fun()

      System.out.println("B说话");

}

}

 

public class C extends A{                  //C继承了A

      public void fun(){                 //重写A类方法fun()

      System.out.println("C说话");

}

}

这时候设计一个speak()方法让一个人说话:

让B说话需要这样写:public void speak(B b)      //传入的参数是B类型的人,不能是A类和C类,只能是B类型的人说话

                                         {b.fun();}

让C说话需要这样写:public void speak(C c)      //传入的参数是C类型的人,只能C类型的人说话

                                         {c.fun();}

这样需要写很多个方法才能满足全部类型的人说话,很不方便

我们可以这样写,使用了多态:

public void   speak(A a){                     //传入父类类型的参数,可以接受任何子类类型的参数,但父类对象名a调用的是子类对象重写的方法fun(),因此实现了多态:一个动作(说话),传入不同的参数(人),出现不同的效果

                a.fun();

}

 

C cman=new c();            // 创建c类对象

B bman=new b();           //创建b类对象

speak(cman);          //用父类A类型,接收了一个子类型对象(向上转型),在调用时,调用的是子类重写的方法cman.fun()

speak(bman);         //用父类A类型,接收了一个子类型对象(向上转型),在调用时,调用的是子类重写的方法bman.fun()

因此这同一个方法输出的是不同的结果,实现了多态


 

多态有耦合度低的好处
如果调用的是子类重写的方法,使用多态更好 更便于维护
如果调用的是子类独有的方法,不使用多态

多态耦合问题
同一个动作,不同的场合,不同的结果

4.把类作为参数传递使用多态


5.把类作为返回值类型使用多态
创建对象和使用对象分离
创建对象交给其他类处理,使用对象在另一个类

6.简单工厂模式
水果类父类 子类:苹果、香蕉、葡萄
设计一个类专门用来创建对象


7.静态方法能继承不能被重写!

8.多态形式 父类 对象名=new 子类();
属性是不会覆盖的
如果调用属性,看等号左边---没有属性的重写
如果调用方法 看等号右边---方法可以被重写

9.里式代换原则(lsp)

父类出现的地方,子类都可以代替
如果参数是Object类型,就可以传递任何对象!
如果返回值是Object类型,就可以返回任何对象!

10.权限修饰符
类用 public
成员变量 private
构造函数以及自定义方法 public

private 只能在这个类中使用
默认的 不加权限修饰符 只能在同一个包中使用
protected 可以在不同的包中使用 并且是继承关系 父类和子类不在同一个包中
public 整个项目都可以用

posted @ 2021-07-19 21:23  墨衣i  阅读(80)  评论(0)    收藏  举报