比如说有一个接口 人, 有两个class实现了这个接口,一个是男人,一个是女人,显然男人和女人撒尿是不一样的,这时,我们有一个方法的接口参数是一个人,里面要调用撒尿这个方法,按你的理解这里就必须给这个方法两个参数,一个是男人,一个是女人,但如果用了接口的话,只需要在接口里定义撒尿这个方法,由男人和女人去具体实现,方法里面调用接口的撒尿这个方法就行了.如果要新增加一个人种,比如说中性人,但撒尿的方式和前两种都不一样,如果用了接口的话,就可以很方便解决这个问题,只需要让中性人也实现人的接口,这个方法就可以调用,不用改动原来的代码
在Java中,能用接口的地方尽量用接口,<Effctive Java>里面讲了一些很好的准则,建议认真去看
(以电脑主机为题)
//计算器类
interface Computer{
public void input(char c);
public char output();
}
//播放器类
interface Player{
public void playCD(CD cd);
public void playMP3(MP3 mp3);
}
//游戏机类
interface GameMachine{
public void playGame(Game game);
}//算盘
class Abaci implements Computer{
public void input(char c){...}
publci char output(){...}
}
//我的机器,继承了算盘的能力,又可以做播放器与游戏机
class MyMachine extends Abaci implements Player, GameMachine{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
public void playGame(Game game){...}
}
class Abaci{
public void input(char c){...}
publci char output(){...}
}class MyMachine extends Abaci{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
public void playGame(Game game){...}
}实现的功能也是一样啊,那么上面定义的接口的意义在哪里?
看个例子:
interface Player{
public void playCD(CD cd);
public void playMP3(MP3 mp3);
}class MyMachine1 implements Player{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
}class MyMachine2 implements Player{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
}class MyMachine3 implements Player{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
}class Test{
public static void main(String[] args){
Player[] player = new Player[3];
player[0] = new Machine1();
player[1] = new Machine2();
player[2] = new Machine3();
for(int i=0;i<3;i++){
CD cd = new CD();
player[i].playCD(cd);
}
}
}
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
}class MyMachine2{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
}class MyMachine3{
public void playCD(CD cd){...}
public void playMP3(MP3 mp3){...}
}class Test{
public static void main(String[] args){
MyMachine1 a = new Machine1();
MyMachine2 b = new Machine2();
MyMachine3 c = new Machine3();
a.playCD(cd);
}
}
倒数3、4行添加b.playCD(cd);,c.playCD(cd);这样做同样可以实现啊,希望继续回答!
我同意 danger1(我很危险,但我也能解决问题) 的说法
==================================================
/**
* @version 1.20 07 Apr 1998
* @author Cay Horstmann
*/import java.util.*;
import corejava.*;public class EmployeeSortTest
{ public static void main(String[] args)
{ Employee[] staff = new Employee[3];. staff[0] = new Employee("Harry Hacker", 35000,
new Day(1989,10,1));
staff[1] = new Employee("Carl Cracker", 75000,
new Day(1987,12,15));
staff[2] = new Employee("Tony Tester", 38000,
new Day(1990,3,15));
ArrayAlg.shellSort(staff);
int i;
for (i = 0; i < staff.length; i++)
System.out.println(staff[i]);
}
}
/*
abstract class Sortable
{ public abstract int compareTo(Sortable b);
}
*/public interface Sortable
{ int compareTo(Sortable b);
}
class ArrayAlg
{ public static void shellSort(Sortable[] a)
{ int n = a.length;
int incr = n / 2;
while (incr >= 1)
{ for (int i = incr; i < n; i++)
{ Sortable temp = a[i];
int j = i;
while (j >= incr
&& temp.compareTo(a[j - incr]) < 0)
{ a[j] = a[j - incr];
j -= incr;
}
a[j] = temp;
}
incr /= 2;
}
}
}class Employee extends Sortable
{ public Employee(String n, double s, Day d)
{ name = n;
salary = s;
hireDate = d;
}
public void raiseSalary(double byPercent)
{ salary *= 1 + byPercent / 100;
}
public String getName() { return name; }
public double getSalary() { return salary; }
public String toString()
{ return name + " " + salary + " " + hireYear();
}
public int hireYear()
{ return hireDate.getYear();
}
public int compareTo(Sortable b)
{ Employee eb = (Employee)b;
if (salary < eb.salary) return -1;
if (salary > eb.salary) return 1;
return 0;
} private String name;
private double salary;
private Day hireDate;
}
==================================================
从这个例子中可以看出:
1. 接口是符合需求的类的描述,是一个约定。比如电脑上的鼠标,业内对接头,击键发出的电子信号作了约定,只要符合这个约定,鼠标就可以用,置于怎么实现,各个厂商有不同的办法。上面例子中只要实现了Sortable的类就可以用ArrayAlg.shellSort进行排序。从而提高了代码的可维护性,可重用性。我们现在需要实现对学生进行排序的功能,只需要定义一个类实现Sortable接口就可以重用上面的代码。
上面的例子中Sortable接口只需要实现一个方法,当有实现多个方法的需要的时候,用接口强制这一点就显得有必要。和使用继承相比,接口显得更灵活实用,也不会产生复杂的类的层次关系。2.接口有增强不同模块间弱耦合性的作用。呵呵,说的太绕了。说白了,就是接口提供了封装的作用,比如鼠标的例子,只要你符合接口的定义,里边你怎么做随你便,需要改动的时候,里边的结构发生了变化,外边不用相应变化。
比如上面的例子, 现在是按照工资排序。
public int compareTo(Sortable b)
{ Employee eb = (Employee)b;
if (salary < eb.salary) return -1;
if (salary > eb.salary) return 1;
return 0;
}
改成按照姓名排序只需要改变compareTo的实现就可以了。再比如,仍是参照工资排序,不过乘工龄作为权值,而且改为升序排序。只需要改
public int compareTo(Sortable b)
{ Employee eb = (Employee)b;
if (salary*gongLing < eb.salary*eb.gongLing) return 1;
if (salary*gongLing > eb.salary*eb.gongLing) return -1;
return 0;
}
3.《设计模式》中提到面向对象程序设计的两个原则:
针对接口编程,而不是针对实现编程。
优先使用对象组合,而不是类继承。这两条原则都在鼓励使用接口。就是说我们做程序的过程,可以分为设计和实现两个层面,这两个层面的分离能够使我们的代码拥有更高的质量,有更好的可维护性,可重用性。需求发生改变的时候,我们的代码可以轻松的修改或扩展。
所以在设计接口时要仔细考虑,否则到PROJECT 进行到中间时才发现接口有问题,会很惨的!
█┏━━━━━┓█
█★专业灌水证★█
█ 中国灌水协会 █
█ ☆荣誉颁发☆ █
█ 〖初窥Java〗 █
█ 【虚心学习】 █
█★专业灌水证★█
█┗━━━━━┛█
█████████