一.抽象类和抽象方法
1.建立这个通用接口的唯一理由是,不同的子类可以用不同的方法表示此接口。
2.如果一个类包含一个或多个抽象方法,该类必须被限定为抽象。成为抽象类并不需要所有的方法都是抽象的,仅需将某些方法声明为抽象的即可。
interface Instrument1 {
int VALUE = 5 ;
//在该类中没有任何方法被声明为是public的,但是它们自动就都是public
void play(Note n);
void adjust();
}
public class Wind1 implements Instrument1{
@Override
public void play(Note n) {
//...
}
@Override
public void adjust() {
//...
}
}
3.完全解耦
只要一个方法操作的是类而非接口,那么你只能使用这个类及其子类。如果你想要将这个方法应用于不在此继承结构中的某个类,接口可以在很大程度上放宽这中限制。
4.Java中的多重继承
interface CanSwim {
void swim();
}
interface CanFly {
void fly();
}
interface CanFight {
void fight();
}
class ActionCharacter {
public void fight(){};
}
//父类已经实现了fight()
public class Hero extends ActionCharacter
implements CanFly , CanFight ,CanSwim{
@Override
public void swim() {
// TODO Auto-generated method stub
}
@Override
public void fly() {
// TODO Auto-generated method stub
}
}
public class MainJava {
public static void t(CanFight x){
x.fight();
}
public static void u(CanSwim x){
x.swim();
}
public static void v(CanFly x){
x.fly();
}
public static void w(ActionCharacter x){
x.fight();
}
public static void main(String[] args) {
Hero h = new Hero();
//当Hero对象被创建时,它可以被传递给这些方法中的任何一个。向上转型
t(h);
u(h);
v(h);
w(h);
}
}
(1)使用接口的核心原因:为了能够向上转型为多个基类型,由此带来的灵活性。第二个原因:与使用抽象基类相同,防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口。
(2)抽象类和接口的选择:如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。
5.通过继承来扩展接口
interface Monster {
void menace();
}
interface DangerousMonster extends Monster{
void destory();
}
interface Lethal {
void kill();
}
public class DragonZilla implements DangerousMonster{
@Override
public void menace() {
// TODO Auto-generated method stub
}
@Override
public void destory() {
// TODO Auto-generated method stub
}
}
//只有接口继承可以继承多个接口
interface Vampire extends DangerousMonster ,Lethal{
void drinkBlood();
}
public class MainJava {
static void u(Monster b){
b.menace();
}
public static void main(String[] args) {
//用接口接收实例
DangerousMonster barney = new DragonZilla();
u(barney);
}
}
6.适配接口
7.接口中的域
(1)因为你放入接口中的任何域都自动是static和final的,所以接口就成为了一种很便捷的用来创建常量组的工具。
(2)初始化接口中的域
//任何域都自动是static和final,大写字母风格
public interface RandVals {
Random RAND = new Random(47);
int RANDOM_INT = RAND.nextInt(10);
}
public class MainJava {
public static void main(String[] args) {
//这些域不是接口的一部分,它们的值被存储在该接口的静态存储区域内
print(RandVals.RANDOM_INT) ;
}
}
8.嵌套接口
public class A {
interface B{
void f();
}
public class BImp implements B{
public void f(){
}
}
public class BImp2 implements B{
public void f(){
};
}
public interface C{
void f();
}
class CImp implements C {
public void f(){
}
}
private class CImp2 implements C {
public void f(){
}
}
private interface D{
void f();
}
private class DImp implements D {
public void f(){
}
}
public class DImp2 implements D {
public void f(){
}
}
public D getD(){
return new DImp2();
}
private D dRef;
public void receiveD(D d){
dRef = d ;
dRef.f();
}
}
interface E {
interface G{
void f();
}
public interface H{
void f();
}
void g();
}
public class MainJava {
public class BImp implements A.B{
public void f(){
}
}
class CImp implements A.C {
public void f(){
}
}
class EImp implements E {
public void g(){
}
}
class EGImp implements E.G{
public void f(){
}
}
class EImp2 implements E{
public void g(){
}
class EG implements E.G{
public void f(){
}
}
}
public static void main(String[] args) {
A a = new A();
//a.getD() can't access A.D
A a2 = new A();
a2.receiveD(a.getD());
}
}
(1)嵌套在另一个接口中的接口自动就是public的,而不能声明为private的
9.接口与工厂
接口是实现多重继承的途径,而生成遵循某个接口的对象的典型方式就是工厂方法设计模式。我们在工厂对象上调用的是创建方法,而该工厂对象将生成接口的某个实现的对象。
//接口:具体类的接口抽象
interface Service {
void method1();
void method2();
}
//接口:工厂类接口抽象
interface ServiceFactory {
Service getServoce();
}
//基类:具体类的基类
public class Implementation1 implements Service{
Implementation1(){
};
public void method1() {
}
public void method2() {
}
}
public class Implementation2 implements Service{
Implementation2() {
}
public void method1() {
}
public void method2() {
}
}
//基类:工厂类基类
public class ImplementationFactory implements ServiceFactory{
public Service getServoce() {
return new Implementation1();
}
}
public class Implementation2Factory implements ServiceFactory{
@Override
public Service getServoce() {
// TODO Auto-generated method stub
return new Implementation2();
}
}
public class MainJava {
public static void serviceConsumer(ServiceFactory fact){
//通过工厂类生成对象
Service s = fact.getServoce();
s.method1();
s.method2();
}
public static void main(String[] args) {
serviceConsumer(new ImplementationFactory());
serviceConsumer(new Implementation2Factory());
}
}
10.在相同的棋盘上下国际象棋和西洋跳棋
(工厂模式:工厂对象将生成接口的某个实现的对象)
interface Game {
boolean move();
}
interface GameFactory {
Game getGame();
}
public class Chess implements Game{
private int moves = 0 ;
private static final int MOVES = 4 ;
public boolean move() {
System.out.println("Chess move "+ moves);
return ++moves != MOVES ;
}
}
public class Checkers implements Game{
private int moves = 0 ;
private static final int MOVES = 3 ;
public boolean move() {
System.out.println("Checkers move "+ moves);
return ++moves != MOVES ;
}
}
public class ChessFactory implements GameFactory{
public Game getGame() {
return new Chess();
}
}
public class CheckersFactory implements GameFactory{
@Override
public Game getGame() {
// TODO Auto-generated method stub
return new Checkers();
}
}
public class MainJava {
public static void playGame(GameFactory factory){
Game s= factory.getGame();
}
public static void main(String[] args) {
playGame(new CheckersFactory());
playGame(new ChessFactory());
}
}