一、接口由来
由于java中类只能单继承。当存在一些不是一类的东西,但是又有相同的行为时,且他们没有逻辑的上的继承关系,实际生活中也没有继承的关系时。
此时继承已经不能满足代码的复用要求;接口就产生了。
它是没有继承关系的类之间的共同行为和属性的集合体。但是它也只能提供抽象的方法,因为每个类的实现都不一样,之间可能没有多大的联系,就没有固定实现过程的必要。它里面的属性也只能是公共的静态常量。
二、接口特点
一般格式为:public interface Nameable{ 属性 方法 }
一般名字后面加上“able"表示这是一个接口,命名和类名一样,每个单词首字母大写。
可以有方法和属性。
方法是默认 公共和抽象的即 public && abstract 写不写不影响,都一样
属性必须是 公共、静态和不变的即 public && static && final
它和抽象类一样,不能被实例化。它只能被类实现。
接口可以多继承接口。也是java里面唯一的多继承。
三、接口意义
1.可以解决没有多继承的遗憾
2.外挂加载
给类添加额外的功能,且不影响原来类的继承关系,不用修改其他类。当以后有具体需求时,设计一个几口。让他实现就行了。
3.接口的多态
实现了 接口类型A的类 都可以调用下面的B方法
方法B(接口类型A 接口形参C){接口形参C.接口方法}
作为实参的 对象类型不限,只要实现了接口A就行,他们可以没有继承关系,但是具有接口A里面的行为。
4.设计原则
隔开解耦原则:定义借口时,尽量将功能分开,减少接口干扰的可能性。也能降低接口之间的耦合度。
接口污染
所谓接口污染就是为接口添加了不必要的职责。在接口中加一个新方法只是为了给实现类带来好处,以减少类的数目。持续这样做,接口就被不断污染,变胖。实际上,类的数目根本不是什么问题,接口污染会带来维护和重用方面的问题。最常见的问题是我们为了重用被污染的接口,被迫实现并维护不必要的方法。
分离客户程序就是分离接口。如果客户程序是分离的,那么相应的接口也应该是分离的,因为客户程序对它们使用的接口有反作用力。通常接口发生了变化,我们就要考虑所有使用接口的客户程序该如何变化以适应接口的变化。如果客户程序发生了变化呢?这时也要考虑接口是否需要发生变化,这就是反作用力。有时业务规则的变化不是那么直接的,而是通过客户程序的变化引发的,这时我们就需要改变接口以满足客户程序的需要。
分离接口的方式一般分为两种,委托和多继承。前者把请求委托给别的接口的实现类来完成需要的职责,后者则是通过实现多个接口来完成需要的职责。两种方式各有优缺点,通常我们应该先考虑后一个方案,如果涉及到类型转换时则选择前一个方案。
胖接口会导致客户程序之间产生不必要的耦合关系,牵一发而动全身。分解胖接口,使客户程序只依赖它需要的方法,从设计上讲,简单易维护,重用度也高。
列子:
public interface FootballListener {
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endofQuarter(int quarter);
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
public class CellPhone implements FootballListener{
private String homeTeam,visitingTeam;//主队,客队名字
private int homeScore,visitingScore;//主队,客队得分
private int currentQuarter;
@Override
public void homeTeamScored(int points) {
// TODO Auto-generated method stub
if(this.homeScore != points){
System.out.println(this.getHomeTeam()+"分数为:"+points);
this.homeScore = points;
}
}
@Override
public void visitingTeamScored(int points) {
// TODO Auto-generated method stub
if(this.visitingScore != points){
System.out.println(this.getVisitingTeam()+"分数为:"+points);
this.visitingScore = points;
}
}
@Override
public void endofQuarter(int quarter) {
// TODO Auto-generated method stub
if(this.currentQuarter != quarter){
System.out.println("本次赛事:"+quarter+"半场结束!");
this.currentQuarter = quarter;
}
}
@Override
public void setHomeTeam(String name) {
// TODO Auto-generated method stub
System.out.println("本赛主队为:"+name);
this.homeTeam = name;
}
@Override
public void setVisitingTeam(String name) {
// TODO Auto-generated method stub
System.out.println("本赛客队为:"+name);
this.visitingTeam = name;
}
public String getHomeTeam() {
return homeTeam;
}
public String getVisitingTeam() {
return visitingTeam;
}
public int getHomeScore() {
return homeScore;
}
public int getVisitingScore() {
return visitingScore;
}
public int getCurrentQuarter() {
return currentQuarter;
}
}
import java.util.ArrayList;
import java.util.Scanner;
public class FootballGame {
private String homeTeam,visitingTeam;//主队,客队名字
private int homeScore,visitingScore;//主队,客队得分
private ArrayList audience;//听众集合
private int quarter = 0;
private CellPhone c;
public FootballGame(){
this.audience = new ArrayList(10);
}
public FootballGame(String homeTeam, String visitingTeam) {
super();
this.homeTeam = homeTeam;
this.visitingTeam = visitingTeam;
audience = new ArrayList(10);
}
public void run(){
while(this.quarter != 2){
this.menu();
this.dosomething(this.choice());
this.homeTeamScored(this.homeScore);
this.visitingTeamScored(this.visitingScore);
this.quarterEnded(this.quarter);
}
}
private void menu(){
System.out.println("1.添加听众 2.增加主队分数 3增加客队分数 " +
" 4.设置主队 5.设置客队 6.半场结束");
}
private int choice(){
int choice;
do{
Scanner scan = new Scanner(System.in);
System.out.println("输入你要选择的操作:");
choice = scan.nextInt();
}while(choice < 1 && choice >6);
return choice;
}
private void dosomething(int choice){
switch(choice){
case 1: //this.c = new CellPhone();
this.addFootballListener(new CellPhone());
break;
case 2:this.homeScore++;
break;
case 3:this.visitingScore++;
break;
case 4:{
Scanner scan = new Scanner(System.in);
System.out.println("请输入主队的名字:");
String homeTeam = scan.next();
this.setHomeTeam(homeTeam);
}
break;
case 5:{
Scanner scan = new Scanner(System.in);
System.out.println("请输入主队的名字:");
String visitingTeam = scan.next();
this.setVisitingTeam(visitingTeam);
}
break;
case 6:this.quarterEnded(this.quarter++);
break;
}
}
private void addFootballListener(FootballListener f){
audience.add(f);
f.setHomeTeam(homeTeam);
f.setVisitingTeam(visitingTeam);
}
private void homeTeamScored(int points){
int size = audience.size();
for(int i = 0;i < size;i++){
FootballListener current = (FootballListener)audience.get(i);
current.homeTeamScored(points);
}
}
private void visitingTeamScored(int points){
int size = audience.size();
for(int i = 0;i < size;i++){
FootballListener current = (FootballListener)audience.get(i);
current.visitingTeamScored(points);
}
}
private void quarterEnded(int quarter){
int size = audience.size();
for(int i = 0 ;i < size;i++){
FootballListener current = (FootballListener)audience.get(i);
current.endofQuarter(quarter);
}
}
private String getHomeTeam() {
return homeTeam;
}
private void setHomeTeam(String homeTeam) {
this.homeTeam = homeTeam;
}
private String getVisitingTeam() {
return visitingTeam;
}
private void setVisitingTeam(String visitingTeam) {
this.visitingTeam = visitingTeam;
}
private int getHomeScore() {
return homeScore;
}
private void setHomeScore(int homeScore) {
this.homeScore = homeScore;
}
private int getVisitingScore() {
return visitingScore;
}
private void setVisitingScore(int visitingScore) {
this.visitingScore = visitingScore;
}
private ArrayList getAudience() {
return audience;
}
private void setAudience(ArrayList audience) {
this.audience = audience;
}
private int getQuarter() {
return quarter;
}
private void setQuarter(int quarter) {
this.quarter = quarter;
}
}
public class TestFootball {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
FootballGame game= new FootballGame();
game.run();
}
}