多态和特殊类

一、多态的概念

多态主要指同一种事物表现出来的多种形态。

语法格式:父类类型 引用变量名 = new 子类类型();

Shape sr = new Rect();

sr.show();

package com.company.com.lagou.task08;

public class Shape {
  private int x;
  private int y;

  public Shape() {
  }

  public Shape(int x, int y) {
      setX(x);
      setY(y);
  }

  public int getX() {
      return x;
  }

  public void setX(int x) {
      this.x = x;
  }

  public int getY() {
      return y;
  }

  public void setY(int y) {
      this.y = y;
  }
  public void show() {
      System.out.println("横坐标: " + getX() + ",纵坐标: " + getY());
  }
}
package com.company.com.lagou.task08;

public class Rect extends Shape {
  private int len;
  private int wid;

  public Rect() {}

  public Rect(int x, int y, int len, int wid) {
      super(x, y);
      setLen(len);
      setWid(wid);
  }

  public int getLen() {
      return len;
  }

  public void setLen(int len) {
      if (len > 0) {
      this.len = len;
  } else {
          System.out.println("长度不合理");
      }
  }

  public int getWid() {
      return wid;
  }

  public void setWid(int wid) {
      if (wid > 0) {
      this.wid = wid;
  } else {
          System.out.println("宽度不合理哦");
      }
  }

  @Override
  public void show() {
      super.show();
      System.out.println("长度是: " + getLen() + ",宽度是: " + getWid());
  }
}
package com.company.com.lagou.task08;

public class ShapeTest {
  public static void main(String[] args) {
      //声明shape类型的引用的对象并打印
      Shape s1 = new Shape(1,2);
      s1.show();//调用shape的show方法
      System.out.println("--------------");
      //声明rect类型的引用的对象并打印
      Rect rt = new Rect(3,4,5,6);
      rt.show();//调用rect的show方法
      System.out.println("--------------");
      //声明shape类型的引用指向rect类型的对象并打印
      Shape s2 = new Rect(7,8,9,10);//相当于rect类型转到shape类型,子类转父类
      s2.show();//编译阶段调用shape的show,运行阶段调用rect的show方法
  }
}
多态的特点

1、当父类类型的引用指向子类类型的对象时,父类类型的引用可以直接调用父类独有的方法。

2、当父类类型的引用指向子类类型的对象时,父类类型的引用不可以直接调用子类独有的方法。

3、对于父子类都有的非静态方法来说,编译阶段调用父类版本,运行阶段调用子类重写的版本(动态绑定)

4、对于父子类都有的静态方法来说,编译和运行阶段都调用父类版本。

引用数据类型之间的转换

1、引用数据类型之间的转换方式有两种:自动类型转化和强制类型转换。

2、自动类型转换主要是指小类型向大类型的转换,也就是子类转父类,也叫做向上转型。

3、强制类型转换主要指大类型向小类型转换,也就是父类转为子类,也叫做向下转型或显式类型转换。

4、引用数据类型之间的转换必须发生在父子类之间,否则编译报错。

5、若强制的目标类型并不是该引用真正指向的数据类型时则编译通过,运行时发生类型转换异常。

6、为了避免上述错误的发生,应该在强转之前进行判断,格式如下:if(引用变量 instanceof 数据类型),判断引用变量指向的对象是否为后面的数据类型。

多态的实际意义

1、多态的实际意义在于屏蔽不同子类的差异性实现通用的编程带来不同的效果。

二、抽象方法的概念

抽象方法主要指不能具体实现的方法并且使用abstract关键字修饰,也就是没有具体方法体。

语法格式:访问权限 abstract 返回值类型 方法名(形参列表);public abstract void cry();

抽象类主要指不能具体实例化的类并且使用abstract关键字修饰,也就是不能创建对象;

抽象类中可以有成员变量,构造方法,成员方法;

package com.company.com.lagou.task08;

public abstract class AbstractTest {
  private int cnt;

  public AbstractTest() {
  }

  public AbstractTest(int cnt) {
      setCnt(cnt);
  }

  public int getCnt() {
      return cnt;
  }

  public void setCnt(int cnt) {
      this.cnt = cnt;
  }

  public static void main(String[] args) {
      //声明该类类型的引用指向该类型的对象
      //AbstractTest at = new AbstractTest();//不能实例化
      //System.out.println("at.cnt = " + at.cnt);
  }
}

抽象类中可以没有抽象方法,也可以有抽象方法;

package com.company.com.lagou.task08;

public abstract class AbstractTest {
  private int cnt;

  public AbstractTest() {
  }

  public AbstractTest(int cnt) {
      setCnt(cnt);
  }

  public int getCnt() {
      return cnt;
  }

  public void setCnt(int cnt) {
      this.cnt = cnt;
  }
  //自定义抽象方法
  public abstract void show();

  public static void main(String[] args) {
      //声明该类类型的引用指向该类型的对象
      //AbstractTest at = new AbstractTest();//不能实例化
      //System.out.println("at.cnt = " + at.cnt);
  }
}

拥有抽象方法的类必须是抽象类,因此真正意义上的抽象类应该是具有抽象方法并且使用abstact关键字修饰类;

抽象类的实际意义

抽象类的实际意义不在于创建对象而在于被继承;

当一个类继承抽象类后必须重写抽象方法,否则该类也变成抽象类,也就是抽象类对子类具体强制性和规范性,因此叫做模板设计模式。

在以后的开发中推荐使用多态的格式,此时父类类型引用直接调用的多有方法一定是父类中拥有的方法,若以后更换子类时,只需要将new关键字后面的子类类型修改而其他地方无需改变就可以立即生效,从而提高了代码的可维护性和可扩展性。

该方式的缺点就是:父类引用不能直接调用子类独有的方法,若调用则需要强制类型转换。

抽象类的应用

abstract跟private不能共同修饰一个方法。private私有方法不能被重写、继承

abstract跟final不能共同修饰一个方法。final修饰的方法只能被继承,不能被重写

abstract跟static不能共同修饰一个方法。

三、接口

接口的概念:比抽象类还抽象的类,提现在所有方法都为抽象方法。

定义类的关键字时class,而定义接口的关键字时interface。

public interface InterfaceTest {
  /*public static final */int CNT = 1; //里面只能由常量
  private void show() {} //从jdk1.9开始,允许接口中出现私有方法
  //public void show();//里面只能由抽象方法(新特性除外),注释重点关键字可以省略,但建议写上
   

}
接口的作用:
public interface Metal {
  public abstract void shine();
}
public interface Money {
  //自定义抽象方法描述购物行为
  public abstract void buy();
}
package com.company.com.lagou.task08;

//使用implements关键字表达实现的关系,支持多实现
public class Gold implements Metal, Money {

    @Override
    public void shine() {
        System.out.println("发出来金黄色的光芒");
    }

    @Override
    public void buy() {
        System.out.println("买了好多好吃的");
    }

    public static void main(String[] args) {
        Metal mt = new Gold();
        mt.shine();

        Money my = new Gold();
        my.buy();
    }
}
类和接口之间的关系

接口只能继承接口,不能继承类;

package com.company.com.lagou.task08;

public interface Runner {
    //自定义抽象放啊
    public abstract void run();
}
package com.company.com.lagou.task08;

public interface Hunter extends Runner {
    //自定义成员方法描述捕猎的行为
    public abstract void hunt();
}
package com.company.com.lagou.task08;

public class Man implements Hunter{

    @Override
    public void hunt() {
        System.out.println("正在追赶一只小白兔");
    }

    @Override
    public void run() {
        System.out.println("奔跑中");
    }

    public static void main(String[] args) {
        //声明接口类型的引用
        Runner runner = new Man();
        runner.run();

        Hunter hunter = new Man();
        hunter.hunt();
    }
}

1、类和类之间,使用extends关键字表达继承关系,支持单继承;

2、类和接口之间,使用implements关键字表达实现关系,支持多实现;

3、接口和接口之间,使用extends关键字表达继承关系,支持多继承;

接口和抽象类的主要区别

1、定义抽象类的关键字是abstract class,而定义接口的关键字是interface;

2、继承抽象类的关键字是extends,而实现接口的关键字是implements;

3、继承抽象类支持单继承,而实现接口支持多实现;

4、抽象类中可以由构造方法,而接口中不可以由构造方法。

5、抽象类中可以由成员变量,而接口中只可以有常量。

6、抽象类中可以有成员方法,而接口中只可以有抽象方法;

7、抽象类中增加方法时子类可以不用重写,而接口中增加方法时实现类需要重写(java8以前的版本)

8、从java8开始增加新特性,接口中允许出现非抽象方法和静态方法,但非抽象方法需要使用default关键字修饰,可以用接口名.方式进行调用;

9、java9开始增加新特性,接口中允许出现私有方法;

任务总结

1、多态

2、抽象类

3、接口

posted @ 2020-09-27 20:30  Andrew037  阅读(176)  评论(0)    收藏  举报