Java教程

Java多态学习总结

本文主要是介绍Java多态学习总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作。

多态性是对象多种表现形式的体现。

比如,我们在不同的窗口使用同一个按键或者热键,它所产生的效果及实现的功能是不一样的,因为其接口重写的方法所实现功能不一样;

再一个,不同厂家生产的键盘,厂商需要根据USB接口生产规范类生产,这样才能接入其他厂商生产的USB设备,而在定义USB接口时,有不同的实现方法;

即,同一个事件发生在不同的对象上会产生不同的结果。

多态存在的三个必要条件(继承、重写、向上转型)


继承

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。

继承的实现,提高了代码的维护性和复用性,减少代码冗余,使代码更加简洁。

一般形式如下:

    class 父类 {}    //父类:基类、超类
    class 子类 extends 父类 {}    //子类:派生类
  • Java 不支持多继承,但支持多重继承。(即子类不可以有两个父类,但允许存在父类的父类)
    public class 父类 {}
    public class 子类A extends 父类 {}
    public class 子类B extends 父类 {}
  • 子类拥有父类非 private 的属性、方法。

  • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

  • 子类可以用自己的方式实现父类的方法。

  • 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

  • 类的继承不改变类成员的访问权限

  • 构造方法是一个类独有的方法不会被它的子类继承,但是子类在实例化对象时,如果子类的构造器没有显示的调用父类的构造器,则将自动调用父类默认的构造器(无参)。

构造方法的方法名必须与类名一样。

构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。

构造方法不能作用是完成对象的初始化工作,他能够把定义对象时的参数传递给对象的域。

构造方法不能由编程人员调用,而要系统调用。

构造方法可以重写,以参数的个数,类型,或排序顺序区分。


关键字

继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承 Object 类。

extends关键字:类的继承是单一继承,一个子类只能拥有一个父类,所以 extends 只能继承一个类。extends 的英文意思是扩展,extends 很好的体现了子类和父类的关系,即子类是对父类的扩展。

implement关键字:变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

super关键字:通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

  • super可以用来引用直接父类的实例变量。
  • super可以用来调用直接父类方法。
  • super()可以用于调用直接父类构造函数。

this关键字:指向自己的引用。

  • 构造方法中指该构造器所创建的新对象;
  • 方法中指调用该方法的对象;
  • 在类本身的方法或构造器中引用该类的实例变量(全局变量)和方法。

final 关键字:声明类,可以把类定义为不能继承的;修饰方法,使该方法不能被子类重写。

instanceof关键字:双目运算符,但因为是由字母组成,所以定义为保留关键字。它用于判断一个对象是否为一个类(接口、抽象类、父类)的实例。(obj instanceof Object;输出结果为Boolean类型)


接口

extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法;

implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用。

extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承;

JAVA中不支持多重继承,但是可以用接口来实现,继承只能继承一个类,但implements可以实现多个接口。

实现一个接口就是要实现该接口的所有的方法(抽象类除外)。

接口中的方法都是抽象的。

多个无关的类可以实现同一个接口,一个类可以实现多个无关的接口。

在实现接口的时候,必须重写抽象接口中的所有方法,即使他是一个空的方法。

重写的时候要保证方法的形参这些类型也是一致的,否则就会报错。

而且一个类可以去实现多个接口,但是extend只能有一个。

抽象

Java语言提供了两种类,分别为具体类和抽象类。

  • 在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
  • 如果一个方法使用 abstract 来修饰,则说明该方法是抽象方法,抽象方法只有声明没有实现。
  • abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中。 
  • 在使用 abstract 关键字修饰抽象方法时不能使用 private 修饰,因为抽象方法必须被子类重写,而如果使用了 private 声明,则子类是无法重写的。
  • 抽象类不能被实例化,否则报错导致编译无法通过。只有抽象类的非抽象子类可以创建对象。
  • 抽象方法只包含一个方法名,而没有方体。
  • 如果一个类包含抽象方法,那么该类必须是抽象类。
  • 任何子类必须重写父类的抽象方法,或者声明自身为抽象类。
    • 特征:抽象方法没有方法体
    •            抽象方法必须存在于抽象类中
    •            子类重写父类时,必须重写父类所有的抽象方法
    • 使用规则:抽象类和抽象方法都要使用 abstract 关键字声明。
    •            如果一个方法被声明为抽象的,那么这个类也必须声明为抽象的。
    •            抽象类不能实例化,也就是不能使用 new 关键字创建对象。

重写

重写是子类对父类允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。

参数列表与被重写方法的参数列表必须完全相同。

返回类型与被重写方法的返回类型必须相同,或者是父类返回值的派生类。

访问权限不能比父类中被重写的方法的访问权限更低。(public>protected>default>private)

父类的成员方法只能被它的子类重写。

声明为 final 的方法不能被重写。

声明为 static 的方法不能被重写,但是能够被再次声明。

子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。

构造方法不能被重写。

如果不能继承一个类,则不能重写该类的方法。

重载

重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

  • 被重载的方法必须改变参数列表(参数个数或类型不一样);
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的检查异常;
  • 方法能够在同一个类中或者在一个子类中被重载。
  • 无法以返回值类型作为重载函数的区分标准。

方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同数量相同而类型和次序不同,则称为方法的重载(Overloading)。

方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样返回值也一样的方法,就称为重写(Overriding)。

重载 是在同一个类中定义多个同名方法,只要它们的形参列表不同即可。

重写 是除方法体不同外全部相同,方法体的不同实现,从而实现不同的父类功能。就是当父类中的方法无法满足子类时,就需要重写。


向上转型

父类引用指向子类对象为向上转型。

父类类型 对象实例名 = new 子类类型();

向上转型就是把子类对象直接赋给父类引用,不用强制转换。

使用向上转型可以调用父类类型中的所有成员,不能调用子类类型中特有成员,最终运行效果看子类的具体实现。

多态的实现方式


对面向对象来说,多态分为编译时多态和运行时多态。编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是大家通常所说的多态性。
 

重写

class C {
    public void out (){
        System.out.println("Override");
    }
}

class A extends C {
    //方法名、参数、返回值都要相同
    public void out (){
        //方法体实现不同
        System.out.println("Override");
        System.out.println("Override");
    }
}

public class Test {
    public static void main(String args[]){
        C c = new C();//C类实例对象
        C a = new A();//A类实例对象
        
        c.out();//执行C类中的out()方法
        a.out();//执行A类中的out()方法
    }
}

接口

import java.lang.*;//引入包

[可见度] interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}
class C {  //父类
    String str = "字符串";
    Boolean boo = true;

    public c (){  //构造方法1
        System.out.println("1");
    }

    public c (String str){  //构造方法2
        System.out.println("2");
    }

    public void out(){
        System.out.println("extends");
    }

    public void up(){
        System.out.println("extends");
    }
}

//接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
//接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。

interface B {  //接口B
    public void shootB();
    public void runB();
}

interface A {  //接口A
    public void shootA();
    public void runA();
}

class Son extends C implement A,B {  //继承C,实现A,B
    
    Boolean boo;

    //若有需要,可重写父类方法
    public Boolean out(){
        this.boo = super.boo;
        System.out.println(super.str);
        return boo;
    }
    
    //实现的接口方法全部重写
    public void shootA(){
        
    }
    public void runA(){
        
    }
    public void shootB(){
        
    }
    public void runB(){
        
    }
}

public class Test{
    public static void main(String args[]){
        Son son = new Son();
        System.out.println(son.boo);
        System.out.println(son.out());
        son.shootA();
        son.runA();
        son.shootB();
        son.runB();
    }
}

抽象类和抽象方法

public abstract class Shape {
    public int width;
    public int height;

    public Shape(int width, int height) {
        this.width = width;
        this.height = height;
    }

    //抽象方法必须存在于抽象类中
    //抽象方法必须被子类重写
    //抽象类和抽象方法都要使用 abstract 关键字声明。
    public abstract double area();
}

这篇关于Java多态学习总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!