多态,抽象类,接口

Java多态

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

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

比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫、小狗、蜥蜴等等。那么我到宠物店说"请给我一只宠物",服务员给我小猫、小狗或者蜥蜴都可以,我们就说"宠物"这个对象就具备多态性。

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

//因为Deer类具有多重继承,所以它具有多态性。以上实例解析如下:

一个 Deer IS-A(是一个) Animal
一个 Deer IS-A(是一个) Vegetarian
一个 Deer IS-A(是一个) Deer
一个 Deer IS-A(是一个)Object

Java中,所有的对象都具有多态性,因为任何对象都能通过IS-A测试的类型和Object类。

访问一个对象的唯一方法就是通过引用型变量。

引用型变量只能有一种类型,一旦被声明,引用型变量的类型就不能被改变了。

引用型变量不仅能够被重置为其他对象,前提是这些对象没有被声明为final。还可以引用和它类型相同的或者相兼容的对象。它可以声明为类类型或者接口类型。

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;
//当我们将引用型变量应用于Deer对象的引用时,以上的声明是合法的,所有的引用型变量都指向相同的对象Deer

多态的实现方法:

重写,接口,抽象类和抽象方法

抽象类

Java 面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类不能实例化对象,但是类的其他功能依然存在,成员变量,成员方法,构造方法的访问方式和普通类一样。

抽象类必须要被继承才能使用,所以在设计阶段就应该决定要不要抽象类

如果父类包含子类集合的常见方法,但是由于父类本身是抽象的,所以不能使用这些方法

//定义一个抽象类,和正常类没有什么不同,存在成员变量,构造器,方法。但是抽象类不能被实例化
public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number)
   {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public double computePay()
   {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   public void mailCheck()
   {
      System.out.println("Mailing a check to " + this.name
       + " " + this.address);
   }
   public String toString()
   {
      return name + " " + address + " " + number;
   }
   public String getName()
   {
      return name;
   }
   public String getAddress()
   {
      return address;
   }
   public void setAddress(String newAddress)
   {
      address = newAddress;
   }
   public int getNumber()
   {
     return number;
   }
}

怎么才能使用定义好的抽象类呢,使用一般的方法继承abstract类

//创建一个类继承抽象类
public class Salary extends Employee
{
   private double salary; //Annual salary
   public Salary(String name, String address, int number, double
      salary)
   {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck()
   {
       System.out.println("Within mailCheck of Salary class ");
       System.out.println("Mailing check to " + getName()
       + " with salary " + salary);
   }
   public double getSalary()
   {
       return salary;
   }
   public void setSalary(double newSalary)
   {
       if(newSalary >= 0.0)
       {
          salary = newSalary;
       }
   }
   public double computePay()
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}
//不能实例化一个抽象类对象,可以通过继承,实例化
public class AbstractDemo
{
   public static void main(String [] args)
   {  
      //实例化继承自抽象类的对象,这个对象将从抽象类继承成员变量和成员方法
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);

      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();

      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
    }
}

抽象方法

抽象方法存在抽象类,接口中。

抽象类中可以存在普通方法,可以没有抽象方法,全部都是普通方法都可以。但是一个类只要有了抽象方法,就一定是抽象类

设计一个抽象类,再设计一个抽象方法,抽象方法中无具体实现,具体实现由它的子类来实现,

抽象方法只有一个方法名,中无方法体

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其余代码
}

任何继承抽象方法的子类必须重写该方法。否则声明子类也是抽象类,最终必须有一个子类实现该抽象方法。

public class Salary extends Employee
{
   private double salary; // Annual salary
  
   public double computePay()    //重写来自父类的抽象方法
   {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }

   //其余代码

接口

接口(Interface)在java中是一个抽象类型,是抽象方法的集合,一个类可以继承接口,从而继承接口的抽象方法。

接口不等于类,只是两者的编写方式很相似。类描述对象的属性和方法,接口包括类要实现的方法。

接口(eg List)无法被实例化,同抽象类相似,但是可以被实现,一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在Java中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

  • 一个接口可以有多个方法。
  • 接口文件保存在.java结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在.class结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法。
  • 接口不能包含成员变量,除了static和final变量。
  • 接口不是被类继承了,而是要被类实现。
  • 接口支持多重继承。
//接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字
interface Animal {
   //接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。接口中的方法都是公有的。
   public void eat();
   public void travel();
}

接口的实现

当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类。

类使用implements关键字实现接口。在类声明中,Implements关键字放在class声明后面。

实现一个接口的语法,可以使用这个公式:

... implements 接口名称[, 其他接口, 其他接口..., ...] ...
public class MammalInt implements Animal{
   //实现Animal接口的eat()方法
   public void eat(){
      System.out.println("Mammal eats");
   }
   //实现Animal接口中的travel()方法
   public void travel(){
      System.out.println("Mammal travels");
   } 

   public int noOfLegs(){
      return 0;
   }

   public static void main(String args[]){
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
} 

实现接口的时候,也要注意一些规则:

  • 一个类可以同时实现多个接口。
  • 一个类只能继承一个类,但是能实现多个接口。
  • 一个接口能继承另一个接口,这和类之间的继承比较相似。

接口的继承 

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。

下面的Sports接口被Hockey和Football接口继承:

public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// 文件名: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// 文件名: Hockey.java
public interface Hockey extends Sports
{
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

接口允许多重继承

public interface Hockey extends Sports, Event

接口中可以不包含任何方法

标识接口

标识接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。

标识接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

例如:java.awt.event包中的MouseListener接口继承的java.util.EventListener接口定义如下:

package java.util;
public interface EventListener
{}

标记接口主要用于以下两种目的:

  • 建立一个公共的父接口:

    正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

  • 向一个类添加数据类型:

    这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值