java类之接口

接口

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

public interface Comparable
{
   int compareTo(Object other);
}

就是说,任何实现Comparable接口的类都需要包含compareTo方法,并且这个方法的参数必须是一个object对象,返回一个整数类型。
接口中所有的方法自动地属于public。
接口还有一个没有明确说明的附加要求:在调用x.compareTo(y)的时候,这个compareTo方法必须确实比较两个对象的内容,并返回比较的结果。当x小于y时,返回一个负数;当x等于y时,返回0;否则返回一个正数。
为了让类实现一个接口,通常需要下面两个步骤:
1)、将类声明为实现给定的接口;
2)、对接口中的所有方法进行定义。
要将类声明为某个接口,需要使用关键字implement:

class Empployee implements Comparable

下面是Employee类需要提高的compareTo方法:

public int compareTo(Object otherObject)
{
    Employee other=(Employee) otherObject;
    return Double.copareTo(salary,other.salary);
}

**警告:**在接口声明中,没有将compareTo方法声明为public,这是因为在接口中的所有方法都自动地是public。不过,在实现接口时,必须把方法声明为public;否则,编译器将认为这个方法的访问属性是包可见性,即类的默认访问属性,之后编译器就会给出试图提供更严格的访问权限的警告信息。

package interfaces;

import java.util.*;

public class EmployeeSortTest {
	public static void main(String[] args)
	{
		ArrayList<Employee> staff=new ArrayList<Employee>();
		staff.add(new Employee("Harry Hacker",35000));
		staff.add(new Employee("Carl Cracker",75000));
		staff.add(new Employee("Tony Tester",38000));
		
		Collections.sort(staff);
		
		for(Employee e:staff)
			System.out.println("name="+e.getName()+"  salary="+e.getSalary());
	}
}
package interfaces;

public class Employee implements Comparable<Employee> {
	private String name;
	private double salary;
	
	public Employee(String n,double s)
	{
		name=n;
		salary=s;
	}
	
	public String getName()
	{
		return name;
	}
	
	public double getSalary() {
		return salary;
	}
	
	public void raiseSalary(double byPrecent)
	{
		salary=salary+salary*byPrecent/100;
	}

	/**
	 * Compare employee by salary
	 * @param other another Employee object
	 * @return a negative value if this employee has a lower salary than 
	 * otherObject ,o if the salary are the same,a positive value otherObject
	 */	
	public int compareTo(Employee other) {
		return Double.compare(salary, other.salary);
	}
}

接口的特性

使用instanceOf检查一个对象是否实现了某个特定的接口:

if(anObject instanceOf Comparable)

接口和抽象类

为什么不把接口类直接设计成抽象类:
使用抽象类表示通用 属性存在这样一个问题:每个类只能扩展一个类。假设Employee已经扩展了一个类,例如person,他就不能再扩展其他类了。
有些程序设计语言允许一个类有多个超类,例如C++。我们将此特性称为多重继承。而java的设计者选择了不支持多继承,其主要原因是多继承会让语言本身变得非常复杂(如同C++,如虚基类、控制规则和横向指针类型转换等),效率也会降低。

默认方法

可以为接口提供一个默认方法。必须用default修饰符标记这样一个方法。

public interface Comparable<T>
{
    default int compareTo(T other)   {return 0;}
}

默认方法可以调用任何其他方法。
如果现在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义了同样的方法,则会产生默认方法冲突。java中为避免默认方法冲突,使用如下规则:
1)超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
2)接口冲突。如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型相同的方法,必须覆盖这个方法来解决冲突。

Comparator接口

Array.sort方法还有另外一个版本,有一个数组和一个比较器作为参数,比较器是实现了Comparator接口的类的实例。

public implements Comparator<T>
{
   int compare(T first,T second);
}

//要按照长度比较字符串,可以定义一个实现了Somparator<String>的类:
class LengthComparator implements Comparator<String>
{
    public int compare(String first,String second)
    {
        return first.length-second-lenght;
    }
}

对象克隆

Cloneable接口指示一个类提供了一个安全的clone方法。
浅拷贝(Shallow Copy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。
在这里插入图片描述
深拷贝:首先介绍对象图的概念。设想一下,一个类有一个对象,其成员变量中又有一个对象,该对象指向另一个对象,另一个对象又指向另一个对象,直到一个确定的实例。这就形成了对象图。那么,对于深拷贝来说,不仅要复制对象的所有基本数据类型的成员变量值,还要为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象图进行拷贝!

简单地说,深拷贝对引用数据类型的成员变量的对象图中所有的对象都开辟了内存空间;而浅拷贝只是传递地址指向,新的对象并没有对引用数据类型创建内存空间。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值