多态是指同一操作作用于不同的目标上,能产生不同的解释和不同的执行办法,通俗来讲便是用一种类型的变量来引用不同的目标,然后调用不同的办法,产生不同的行为。多态是完成面向目标的软件技能中必不可少的一个内容。

承继和多态

让咱们以一只动物为例:狗是一种动物,它会跑;猫也是一种动物,它会走。如果咱们想用一个办法来描绘它们的运动行为,该怎么做呢?

咱们能够先界说一个 Animal 类,里边包括一个 move() 办法,来描绘它们共同的运动办法:

public class Animal {
   public void move() {
      System.out.println("动物正在移动");
   }
}

然后,咱们能够在 Animal 的子类中,重写 move() 办法,以完成不同的运动办法:

public class Dog extends Animal {
   public void move() {
      System.out.println("小狗在跑");
   }
}
public class Cat extends Animal {
   public void move() {
      System.out.println("小猫在走");
   }
}

这儿咱们让 Dog 类重写了 move() 办法,完成了“跑”这种运动办法;而 Cat 类重写了 move() 办法,完成了“走”这种运动办法。

终究,咱们能够在主函数中,界说一个 Animal 类型的变量,并别离用 Dog 和 Cat 的实例来赋值,这样咱们就能够用相同的办法名 move() 来调用不同的完成,即完成多态的作用:

public class Test {
   public static void main(String args[]) {
      Animal animal = new Animal();
      Animal dog = new Dog();
      Animal cat = new Cat();
      animal.move(); // 输出动物正在移动
      dog.move();    // 输出小狗在跑
      cat.move();    // 输出小猫在走
   }
}

在上述示例中,咱们界说了 Animal 父类和 Dog、Cat 两个子类。在主函数中,咱们别离声明晰一个父类目标、一个 Dog 目标和一个 Cat 目标。当咱们调用它们的 move() 办法时,表明动物正在移动、小狗在跑和小猫在走,这便是多态的完成原理。

接口和多态

除了承继,接口也能够协助咱们完成多态的功用。接口是指一组办法的调集,类能够完成这些办法并重写它们。和承继不同的是,一个类能够完成多个接口,然后完成多态的作用。

例如,咱们能够界说一个接口 Run,其间包括一个 run() 办法,它表明一些能够奔驰的东西。然后咱们能够在一个类中完成这个接口,并完成其间的办法,以表明详细的奔驰行为。终究,在代码中,咱们能够用接口类型来声明一个变量,然后完成对多个完成类的引用。

下面是一个简略的 Java 程序示例:

public interface Run {
   void run();
}
public class Dog implements Run {
   public void run() {
      System.out.println("小狗在跑");
   }
}
public class Cat implements Run {
   public void run() {
      System.out.println("小猫在走");
   }
}
public class Test {
   public static void main(String[] args) {
      Run dog = new Dog();
      Run cat = new Cat();
      dog.run(); // 输出小狗在跑
      cat.run(); // 输出小猫在走
   }
}

在上述示例中,咱们界说了一个 Run 接口,它包括一个 run() 办法。然后咱们能够在一个类中完成这个接口,并完成其间的办法,以表明详细的奔驰行为。终究,在主函数中,咱们别离声明晰一个 Dog 类型、一个 Cat 类型的变量,并用它们的实例进行赋值和调用,然后完成多态的作用。

办法重载和多态

办法重载是指在同一个类或一个类的承继结构中,运用相同的办法名,但要求参数类型或个数不同,使得一个类拥有多个具有不同参数的办法,自动匹配到不同的办法完成。办法的重载能够让咱们更好地重用代码和完成更加灵活的办法调用。

例如,咱们能够重载一个 add() 办法,使得它既能够完成整数相加,又能够完成小数相加。在代码中,咱们能够用相同的办法名 add() 来调用这两种不同的办法,终究调用的办法取决于实参类型。

下面是一个简略的 Java 程序示例:

public class Calculation {
   public void add(int a, int b) {
      System.out.println("两个整数相加的成果是:" + (a + b));
   }
   public void add(double a, double b) {
      System.out.println("两个小数相加的成果是:" + (a + b));
   }
}
public class Test {
   public static void main(String args[]) {
      Calculation calculation = new Calculation();
      calculation.add(10, 20);  // 输出两个整数相加的成果是:30
      calculation.add(1.2, 3.4); // 输出两个小数相加的成果是:4.6
   }
}

在上述示例中,咱们界说了一个 Calculation 类,其间包括了两个相同称号、但参数类型不同的 add() 办法,一个是将两个整数相加,另一个是将两个小数相加。在主函数中,咱们别离调用这两个办法,并别离输出它们的成果。这展现了编译时多态的完成原理。

办法覆盖和多态

办法覆盖是指子类重写了父类中的某个办法,并且子类中的办法和父类中的办法具有相同的办法称号、回来类型和参数列表。当咱们运用父类类型来声明一个变量,并将其赋值为子类的实例时,该变量将会调用子类中的办法,完成动态多态的作用。

例如,咱们能够界说一个新的类 Panther,它承继自 Animal 类,然后重写了 move() 办法,以完成新的运动办法。终究,在主函数中,咱们能够用 Animal 类型来声明一个变量,并将其别离赋值为 Dog、Cat 和 Panther 的实例,用 move() 办法来调用它们的运动行为,完成动态多态的作用。

下面是一个简略的 Java 程序示例:

public class Panther extends Animal {
   public void move() {
      System.out.println("黑豹在奔驰");
   }
}
public class Test {
   public static void main(String[] args) {
      Animal animal1 = new Animal();
      Animal animal2 = new Dog();
      Animal animal3 = new Cat();
      Animal animal4 = new Panther();
      animal1.move(); // 输出动物正在移动
      animal2.move(); // 输出小狗在跑
      animal3.move(); // 输出小猫在走
      animal4.move(); // 输出黑豹在奔驰
   }
}

在上述示例中,咱们界说了一个 Panther 类,它承继自 Animal 类,然后重写了 move() 办法,以完成新的运动办法。在主函数中,咱们别离声明晰一个父类目标、一个 Dog 目标、一个 Cat 目标和一个 Panther 目标,并用它们的实例进行赋值和调用,终究调用的办法取决于实际目标的类型,这便是运转时多态的完成原理。

多态原理剖析

多态能够分为编译时多态和运转时多态两种。

运转时多态

运转时多态又称动态多态,是指在程序运转期间依据目标的类型来确认办法的调用。运转时多态是经过办法重写和接口完成来完成的。

上述的动物类 Animal,它拥有一个 move() 办法来描绘动物的运动行为,这个move() 详细调用哪个办法(Animal/Dog/Cat)在编译期间是不知道的,它是在运转期间确认的,在运转期间给他传入什么目标它就调用什么办法。

编译时多态

编译时多态又称静态多态,是指在编译期间就确认了办法的调用。编译时多态是经过办法重载来完成的,即同一个类中有多个称号、参数不同的办法,编译器在调用这些办法时,会依据实参类型的不同来匹配相应的办法。

经过JDBC了解动态

JDBC 是 Java 数据库衔接的标准接口,它答应 Java 应用程序经过统一的接口拜访不同的数据库。运用 JDBC 能够衔接多种数据库,如 MySQL、Oracle、SQL Server 等,这就要求 JDBC 具有言语无关性,能够在运转时动态确认即将衔接的数据库类型,这样才能支撑多种数据库的衔接。

JDBC 中用到的多态主要是运转时多态。JDBC 接口界说了一些通用的办法和接口,如 Connection、Statement、ResultSet 等,它们都是抽象类或接口。详细的数据库驱动程序完成了这些办法和接口,经过完成这些办法和接口,完成了衔接到详细的数据库。在衔接数据库时,咱们经过 DriverManager 的 getConnection() 办法获取 Connection 目标,此刻是用的是 JDBC 接口,而不是详细的数据库驱动衔接,只有在运用 Connection 目标的时候才会动态判别实际运用的数据库类型。以下是一个简略的 JDBC 衔接 MySQL 数据库的示例代码:

String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);

在上述代码中,咱们仅仅经过 JDBC 接口衔接到 MySQL 数据库,并没有运用详细的 MySQL 驱动程序。当咱们调用 conn.prepareStatement() 办法时,此刻才依据详细的数据库类型获取到一个完成了 PreparedStatement 接口的目标,例如 MySQLPreparedStatement。这便是在运转时动态确认要运用的数据库类型,完成了运转时多态的作用。

总之,JDBC 中充分利用了 Java 的多态特性,经过动态绑定技能,完成了在不同数据库之间切换时的言语无关性。JDBC 衔接的抽象规划,能够让咱们编写一次衔接代码,就能够衔接多个数据库,完成了代码复用和可扩展性。

总结

多态是 Java 面向目标编程中的重要概念。它答应咱们在编写代码时,只需要知道一个目标的类型,而无需知道它所详细归于的子类类型。在 Java 中,多态的完成原理主要有两种办法:运转时多态和编译时多态。前者是经过办法的重写完成的,后者则是经过办法的重载完成的。一起,多态也让 Java 的代码更加灵活、可扩展性更强。

重视微信大众号(每天一篇文章):小虎哥的技能博客