java 接口和抽象类

参考:《JAVA核心技术 卷I:基础知识》


#################################################################


接口技术:主要用来描述类具有什么功能,而并不给出每个功能的具体实现。一个类可以实现(implement)一个或多个接口,并在需要接口的地方,随时使用实现了相应接口的对象。


在Java程序设计语言中,接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。


接口的特性:

1.接口不是类,尤其不能使用new运算符实例化一个接口:

x = new Comparable(. . .); //ERROR

2.可以声明接口的变量:

Comparable x; //OK

接口变量必须实现引用了接口的类对象:

x = new Employee(. . .); //OK provided Employee implements Comparable

3.可以使用instanceof运算符检查一个对象是否实现了某个特定的接口:

if (anObject instanceof Comparable) {. . .}

4.接口可以被扩展。允许存在多条从具有较高通用性的接口到较高专用性的接口的链:

例如,接口Moveable如下:

public interface Moveable {
        void move(double x, double y);
}

以它为基础扩展一个叫做Powered的接口:

public interface Powered extends Moveable {
        double move2()
}

5.接口中不能包含实例域或静态方法,但可以包含常量:

public interface Powered extends Moveable {
        double move2();
        double SPEED_LIMIT = 90; // a public static final constant
}
接口中的所有方法都自动设为public,所有常量域都自动设为public static final
实例域解释: http://zhidao.baidu.com/link?url=t6nNhJ5KZlquXKw4bYRcfhLPoHbEuxKtMjSEvdHNV79jFC_uxVUPLTXHfttJnwUJ01Cln5pp9mgFlKVXJGj_PK


###################################


抽象类

类中含有关键字abstract定义的函数即称为抽象类,其中关键字abstract定义的函数称为抽象函数,抽象函数不需要实现这个方法:

public abstract String getHello();//no implemention required

为了提高程序的清晰度,包含一个或多个抽象方法的类本身必须被声明为抽象的:

abstract class Person {
        . . .
        public abstract String getHello();
}


除了抽象方法,抽象类还可以包含具体数据和具体方法:

abstract class Person {
        public Person(String n) {
                name = n;
        }

        public abstract String getHello();

        public String getName() {
                return name;
        }

        private String name;
}

建议尽量将通用的域和方法(不管是否是抽象的)放在超类(不管是否是抽象的)中。

抽象方法充当着占位的角色,它们的具体实现在子类中。扩展抽象类可以有两种选择。一种是在子类中定义部分抽象方法或抽象方法也不定义,这样就必须将子类也标记为抽象类;另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了。

例如,通过扩展抽象Person类,并实现getHello()方法来定义Student类。由于在Student类中不再含有抽象方法,所以不必将这个类声明为抽象的。


类即使不含抽象方法,也可以将类声明为抽象类。

抽象类不能被实例化。也就是说,如果将一个类声明为abstract,就不能创建这个类的对象。

new Person("zj"); //ERROR

抽象类可以作为对象变量,但是它只能引用非抽象类的子类。

Person p = new Student("zj");
在这里p是一个抽象类Person的变量,它引用了一个非抽象子类Student的实例


###################################################################################


接口实例

Arrays类中的sort方法承诺可以对对象数组进行排序,但要求满足下列前提:对象所属的类必须实现了Comparable接口

Comparable接口位于java.lang包,其中只有一个函数:

package java.lang;
import java.util.*;
public interface Comparable<T> {
    public int compareTo(T o);
}
也就是说,任何实现Comparable接口的类都需要包含compareTo方法

note:接口中的所有方法自动地属于public。因此,在接口中声明方法时,不必提供关键字public。不过在实现接口时,必须把方法声明为public


让类实现一个接口,通常需要下面两个步骤:

1)将类声明为实现给定的接口

2)对接口中的所有方法进行定义

要将类声明为实现某个接口,需要使用关键字implements:

class Employee implements Comparable<Employee>

同时,上面的Employee类需要提供compareTo方法:

	public int compareTo(Employee em) {
		if (salary < em.salary) 
			return -1;
		if (salary > em.salary) 
			return 1;
		return 0;
	}


实现雇员数组排序的全部代码:

import java.util.*;

/**
 * this program demonstrates the use of the Comparable interface
 * @author zj
 *
 */
public class EmployeeSortTest {
	public static void main(String[] args) 
	{
		Employee[] staff = new Employee[3];
		
		staff[0] = new Employee("hk", 25000);
		staff[1] = new Employee("zj", 33000);
		staff[2] = new Employee("dh", 10000);
		
		Arrays.sort(staff);
		
		//print out information about all Employee objects
		for (Employee e : staff) 
		{
			System.out.println("name  = "+e.getName()+", salary = "+e.getSalary());
		}
	}
}

class Employee implements Comparable<Employee>
{
	public Employee(String n, double s)
	{
		name  = n; 
		salary = s;
	}
	
	public String getName()
	{
		return name;
	}
	
	public double getSalary()
	{
		return salary;
	}
	
	public void raiseSalary(double byPercent) 
	{
		double raise = salary * byPercent / 100;
		salary += raise;
	}
	
	/**
	 * Compares Employee by salary
	 * @param other another Employee object
	 * @return a negative value if this employee has a lower salary than otherObject,
	 *  0 if the salaries are the same, a positive value otherwise
	 */
	public int compareTo(Employee other) 
	{
		if (salary < other.salary) 
			return -1;
		if (salary > other.salary)
			return 1;
		return 0;
	}
	
	private String name;
	private double salary;
}



############################################################


抽象类实例


import java.util.*;

/**
 * This program demonstrates abstract classes
 * @author zj
 *
 */
public class PersonTest {
	public static void main(String[] args) 
	{
		Person[] people = new Person[2];
		
		//fill the peopel array with Student and Employee objects
		people[0] = new Employee("Hk", 5000, 1989, 10, 1);
		people[1] = new Student("zj", "computer science");
		
		//print out names and descriptions of all Person objects
		for (Person p : people)
		{
			System.out.println(p.getName() + ", " + p.getDescription());
		}
	}
}

abstract class Person 
{
	public Person(String n)
	{
		name = n;
	}
	
	public abstract String getDescription();
	
	public String getName()
	{
		return name;
	}
	
	private String name;
}

class Employee extends Person
{
	public Employee(String n, double s, int year, int month, int day)
	{
		super(n);
		salary = s;
		GregorianCalendar calendar = new GregorianCalendar(year, month - 1 , day);
		hireDay = calendar.getTime();
	}
	
	public double getSalary()
	{
		return salary;
	}
	
	public Date getHireDay()
	{
		return hireDay;
	}
	
	public String getDescription()
	{
		return String.format("an employee with a salary of $%.2f", salary);
	}
	
	public void raiseSalary(double byPercent)
	{
		double raise = salary * byPercent / 100;
		salary += raise;
	}
	
	private double salary;
	private Date hireDay;
}

class Student extends Person
{
	/**
	 * @param n the Student's name
	 * @param m the Student's major
	 */
	public Student(String n, String m)
	{
		//pass n to superclass constructor
		super(n);
		major = m;
	}

	public String getDescription()
	{
		return "a student majoring in "+major;
	}
	
	private String major;
}



###############################################


每个类只能扩展一个类,但每个类可以实现多个接口

Java语言利用接口机制来实现多继承的大部分功能


你可能感兴趣的:(java)