天天看點

Java學習總結 【多态 抽象類 接口】

多态、抽象類、接口

      • 多态
      • 抽象類
      • 接口

多态

多态存在的條件:

1.建立在繼承關系上

2.發生向上轉型(父類引用指向子類的執行個體)

3.子類必須重寫和父類同名的方法

具體來看多态示例吧

class Shape{
    public void draw(){
   
    }
}

class Cycle extends Shape{
    @Override   //注解 表示有方法重寫同時友善檢查重寫方法
    //重寫了父類Shape的draw方法,對于下面的Rect和Floewr也一樣
    public void draw() {
        System.out.println("○");
    }
}

class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println('□');
    }
}

class Flower extends Shape{
    @Override
    public void draw() {
        System.out.println("❀");
    }
}

//以上為類的實作者編寫
//======================來一條分割線助威==============================//
//以下為類的調用者編寫

public class TrqDemo {
    public static void main(String[] args) {
        Shape shape1 = new Cycle();   //父類引用shape1指向子類Cycle對象
        Shape shape2 = new Rect();
        Shape shape3 = new Flower();
        //向上轉型發生時機有三種:①直接指派調用 ②方法傳參 ③方法傳回值
        //在這裡我們使用: 方法傳參
        drawShape(shape1);   
        drawShape(shape2);
        drawShape(shape3);

    }

    public static void drawShape(Shape shape){
        shape.draw();
    }
}
           
Java學習總結 【多态 抽象類 接口】

通過上面的例子相信大家對多态一目了然,那麼多态的好處是什麼呢?

1.讓類的調用者不需要這個類的類型是什麼,隻需要知道對象是否具有某個方法即可

==2.降低代碼的“圈複雜度”,避免使用了大量的if-else

抽象類

在上面的列印圖形示例中,我們發現Shape父類中draw方法沒有實際的實作,主要的繪制都是子類中的draw方法實作的,對于這種沒有具體實作的方法,我們可以将它設計為抽象方法(abstract method),包含抽象方法的類,我們稱之為抽象類(abstract class)

具體來看抽象類示例吧

抽象類:最大的意義為了被繼承

1.抽象類不能被直接執行個體化
2.抽象方法不能被private修飾,因為抽象方法就是用來被重寫的
3.抽象類中可以包含其他的非抽象方法,可以包含字段,非抽象方法和普通方法一樣可被重寫,可被子類調用
4.抽象類可被普通類與抽象類繼承。被普通類繼承時,普通類中一定要重寫抽象類中的抽象方法;被抽象類繼承時,可什麼都不寫;對于兩個普通類之間的繼承,子類裡面可以什麼都不寫
5.對于抽象類,要想達到執行個體化效果,隻能建立抽象類的子類,讓子類重寫抽象類中的抽象方法
6.抽象類也可以發生向上轉型
           
abstract class Shape{
    abstract public void draw();
//    abstract protected void draw(); 可以
//    abstract void draw();  可以
//    abstract private void draw(); 堅決不可以被private修飾


    void fine(){
        System.out.println("fine!!!");
    }
}

class Rect extends Shape{

    @Override
    //這裡draw方法必須被public修飾 對于重寫而言 子類方法通路權限必須大于父類
    public void draw(){
        System.out.println("□□□");
    }
}


//普通類繼承抽象類,普通類不想實作抽象類中的抽象方法時,可被修飾為抽象類
abstract class Cycle extends Shape{

}


public class TrqDemo1 {
    public static void main(String[] args) {
//        Shape shape = new Shape();    編譯錯誤,抽象類不能被執行個體化

        Shape shape = new Rect();
        shape.draw();   //直接指派

        drawMap(new Rect()); //方法傳參

        drawMap().draw(); //方法的傳回值
    }

    public static void drawMap(Shape shape){
        shape.draw();
    }


    public static Shape drawMap(){
         Rect rect = new Rect();
         return rect;
    }

}
           
Java學習總結 【多态 抽象類 接口】

接口

接口是抽象類的更進一步,抽象類中除了抽象方法還可以包含非抽象方法和字段,而對于接口,接口中方法隻能為抽象方法,字段隻能為靜态常量。可以算抽象類的特殊形式,用interface修飾。

接口: 關鍵字interface   接口最大的意義讓Java實作了多繼承的效果

1.抽象類還可以包含非抽象方法和字段,而接口的方法都是抽象方法用public abstract修飾,字段隻能包含靜态常量用public static final修飾
2.JDK1.8引入新的特性,default修飾的方法可以有具體的實作
3.接口無法執行個體化
4.接口與類之間的關系是implements
5.一個類可以實作多個接口;一個類繼承一個父類同時也可以實作多個接口
6.一個接口可以擴充多個接口通過extends實作
7.接口的出現就是為了解決Java多繼承問題
           

接口執行個體1:一個類實作一個接口

interface IShape{
    public abstract void draw();  //public和abstract可丢棄
    public static final int val=66;
}

//展示了普通類和接口之間的關系
class Cycle implements IShape{
    @Override
    public void draw(){
        System.out.println("⚪");
    }
}

public class TrqDemo2{
    public static void main(String[] args) {
        IShape shape = new Cycle();
        shape.draw();  //直接指派調用

        drawMap(shape); //方法傳參

        drawMap().draw(); //方法傳回值調用

    }

    public static void drawMap(IShape shape){
        shape.draw();
    }

    public static IShape drawMap(){
        return new Cycle();
    }
}
           
Java學習總結 【多态 抽象類 接口】

接口執行個體2:一個類實作多個接口

//表示一組動物
class Animal{
    protected String name;

    public Animal(String name){
        this.name = name;
    }
}

//一組接口
interface IFlying{
    void fly();
}
interface IRunning{
    void run();
}
interface ISwimming{
    void swim();
}

//建立具體的動物類

class Cat extends Animal implements IRunning{
    public Cat(String name){
        super(name);
    }
    
    @Override
    public void run(){
        System.out.println(this.name + "正在跑!");
    }
}

class Fish extends Animal implements ISwimming{
    public Fish(String name){
        super(name);
    }

    @Override
    public void swim(){
        System.out.println(this.name + "正在遊!");
    }
}

class Frog extends Animal implements IRunning,ISwimming{

    public Frog(String name){
        super(name);
    }

    @Override
    public void run(){
        System.out.println(this.name + "正在往前跳!");
    }
    
    @Override
    public void swim(){
        System.out.println(this.name + "正在遊泳!");

    }
}

class Duck extends Animal implements ISwimming,IFlying,IRunning{
    public Duck(String name){
        super(name);
    }

    @Override
    public void fly() {
        System.out.println(this.name + "正在用翅膀飛!");
    }
    
    @Override
    public void run() {
        System.out.println(this.name + "正在用兩條腿跑!");
    }
    
    @Override
    public void swim() {
        System.out.println(this.name + "正在水上漂!");
    }
}

//Robot沒有繼承類 擴充了一個接口
class Robot implements  IRunning{

    public String name;
    public Robot(String name){
        this.name = name;
    }
    
    @Override
    public void run() {
        System.out.println(this.name + "機器人正在跑!");
    }
}

public class TrqDemo3 {

    public static void main(String[] args) {
        IRunning run = new Robot("機器一号");
        run.run();

        gofly(new Duck("唐小鴨"));
        goRun(new Cat("唐小貓"));
        goSwim(new Frog("唐小蛙"));
    }

    public static void gofly(IFlying fly){
        fly.fly();
    }

    public static void goRun(IRunning run){
        run.run();
    }

    public static void goSwim(ISwimming swim){
        swim.swim();
    }
}
           
Java學習總結 【多态 抽象類 接口】

接口執行個體3:接口擴充多個接口

     一個類繼承一個父類同時實作多個接口

interface A {
    void funcA();
}
interface B {
    void funcB();
}
interface C {
    void funcC();
}

//接口也可以擴充多個接口
interface D extends A,B,C{
    void funcD();
}

//接口D擴充了三個接口,是以在類T中必須實作重寫四個抽象方法
class T implements D{
    @Override
    public void funcA() {
    }
    
    @Override
    public void funcD() {
    }
    
    @Override
    public void funcB() {
    }
    
    @Override
    public void funcC() {
    }
}


abstract class TestAbstract {
    public abstract void funcAbstract();
}

//一個普通類繼承一個父類同時實作多個接口
class Test extends TestAbstract implements A,B,C{
    @Override
    public void funcA() {
    }
    
    @Override
    public void funcB() {
    }
    
    @Override
    public void funcC() {
    }
    
    @Override
    //普通類繼承抽象類時,必須重寫父類抽象方法
    public void funcAbstract() {
    }
}

public class TrqDemo4 {
    public static void main(String[] args) {

    }
}
           

明天光芒依舊,加油。1.18