java编程思想-----多态接口

多态

8.3构造器和多态

  1. 尽管构造器并不具有多态性(它们实际上是static方法,只不过该static声明是隐式的)
  2. 构造器调用顺序:
    1. 调用基类构造器.
    2. 按声明顺序调用成员初始化方法.
    3. 调用导出类构造器主体.
  3. 上2初始化顺序并不完整
    1. 在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零.
    2. 如前所述的那样调用基类构造器.
    3. 按声明顺序调用成员初始化方法.
    4. 调用导出类构造器主体.
//本例中存在两个知识点
//1. 如果要调用构造器内部的一个动态绑定的方法,就要用到那个方法的覆盖后的定义.
//2. 在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零.
//即初始化radius为0
class Glyph{
    void draw(){
        print("Glyph.draw()");
    }
    Glyph(){
        print("Glyph() before draw()");
        draw();
        print("Glyph() after draw()");
    }
}
class RoundGlyph extends Glyph{
    private int radius = 1;
    RoundGlyph(int r){
        radius = r;
        print("RoundGlyph.draw(). radius = " + radius);
    }
    void draw(){
        print("RoundGlyph.draw().radius" + radius);
    }
}
public class PolyConstructors {
    public static void main(String[] args) {
        new RoundGlyph(5);
    }
}/*Ouput:
Glyph() before, radius = 0
Glyph() after draw ()
RoundGlyph.RoundGlyph(), radius = 5
  1. 因此编写构造器时有一条有效准则:”用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法”.
  2. 在构造器内唯一能够安全调用的那些方法时基类汇总的final方法(也适用private方法,它们自动属于final方法).
  3. 用继承表达行为间的差异,并用字段表达状态上的变化.附代码
class Actor{
    public void act(){}
}
class HappyActor extends Actor{
    public void act(){
        print("HappyActor");
    }
}
class SadActor extends Actor{
    public void act(){
        print("SadActor");
    }
}
class Stage{
    private Actor actor = new HappyActor();
    public void change(){
        actor = new SadActor();
    }
    public void performPlay(){
        actor.act();
    }
}
public class Transmogrify {
    public static void main(String[] args) {
        Stage stage = new Stage();
        stage.performPlay();
        stage.change();
        stage.performPlay();
    }
}

接口

9.1抽象类和抽象方法

  1. 如果从一个抽象类继承,并想创建该新类的对象,那么就必须为基类中的所有抽象方法提供定义.
  2. 这个题比较有意思我写下来.
    创建一个不包含任何方法的抽象类,从哪里导出一个类,并添加一个方法.创建一个静态方法,他可以接收指向基类的引用,将其向下转型到导出类,然后再调用该静态方法,在main()中,展现它的运行情况.然后,为基类中的方法加上abstract声明,这样就不再需要进行向下转型.
abstract class Dad {}  

class Son extends Dad {  
    protected void print() { System.out.println("Son"); }  
}  

abstract class SecondDad {  
    abstract protected void print();  
}  

class SecondSon extends SecondDad {  
    protected void print() { System.out.println("SecondSon"); }  
}  

public class Ja9_1_4 {  
    public static void testPrint(Dad d) {  
        ((Son)d).print();//it's necessary  
    }  
    public static void secondTestPrint(SecondDad sd) {  
        sd.print();//don't need ((SecondSon)sd)  
    }  
    public static void main(String[] args) {  
        Son s = new Son();  
        Ja9_1_4.testPrint(s);  
        SecondSon ss = new SecondSon();  
        Ja9_1_4.secondTestPrint(ss);
    }  
}  
  1. 续接口,接口中在jdk1.8后可以default声明关键字

9.2 接口

  1. Interface关键字使抽象的概念更向前迈进了一步.abstract关键字允许人们在类中创建一个或多个没有任何定义的方法–提供了接口部分,但是没有提供任何相应的具体实现,这些实现是由类的继承者创建的.

Interface这个关键字产生了一个完全抽象的类,他根本就没有提供任何具体实现.他允许创建者确定方法名 参数列表和返回类型,但是没有任何方法体.接口只提供了形式,而未提供任何具体实现.

  1. interface不仅仅是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类的类型,来实现某种类似多重继变种的特性.
  2. 就像类一样,可以在interface关键字前面添加public关键字,如果不添加public关机找你,则它只有包访问权限,这样它就只能在同一个包内可用.接口也可以包含域,但是这些域隐式地是static和final的.
  3. 可以选择在接口中显式地方法声明为public的,但即使你不这么做,他们也是public的.

9.3完全耦合

  1. 用代码来解释一下耦合关系(刚开始没有看懂第二天又看才看懂)
//看两点
//1. class Processor   而不是  interface Processor(现象:完全耦合.造成应用领域太小)
//2. //如果Process是一个接口,那么这些限制就会变得松动,是的你可以复用结构该接口的Apply.process().

class Processor{//public interface Processor{String name(); Object process(Object input);}
    public String name(){
        return getClass().getSimpleName();
    }
    Object process(Object input){
        return input;
    }

}
class Upcase extends Processor{
    String process(Object input){
        return ((String)input).toUpperCase();
    }
}
class Downcase extends Processor{
    String process(Object input){
        return ((String)input).toLowerCase();
    }
}
class Splitter extends Processor{
    String process(Object input){
        // The split() argument divides a String into pieces;
        return Arrays.toString(((String)input).split(" "));
    }
}




//现在我们发现了一组电子滤波器  看起来是和上面的差不多,但是我们不能够取用主方法里面的Apply.process()方法  
//那么通过下面的代码就可以看出来   这样写代码的复用性太差.

public class Waveform {
    private static long counter;
    private final long id = counter++;
    public String toString(){
        return "Waveform "+ id;
    }
}
public class Filter {
    public String name(){
        return getClass().getSimpleName();
    }
    public Waveform process(Waveform input){
        return input;
    }
}
public class LowPass extends Filter {
    double cutoff;
    public LowPass(double cutoff){
        this.cutoff = cutoff;
    }
    public Waveform process(Waveform input){
        return input;//Dummy processing
    }
}
public class HighPass extends Filter {
    double cutoff;
    public HighPass(double cutoff){
        this.cutoff = cutoff;
    }
    public Waveform process(Waveform input){
        return input;
    }
}
public class BandPass extends Filter {
    double lowCutoff,highCutoff;
    public BandPass(double lowCut,double highCut){
        lowCutoff = lowCut;
        highCutoff = highCut;
    }
    public Waveform Process(Waveform input){
        return input;
    }
}

//这样,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式
public class Apply {
    public static void process (Processor p,Object s){
        print("Using Processor " + p.name());
        print(p.process(s));
    }
    public static String s = "Disagreement with beliefs is by definition incorrect";
    public static void main(String[] args){
        process(new Upcase(),s);
        process(new Downcase(),s);
        process(new Splitter(),s);
    }
}
  1. 解耦 适配器模式
class FilterAdapter implements Process{
    Filter filter;
    public FilterAdapter(Filter filter){
        this.filter = filter;
    }
    public String name(){
        return filter.name();
    }
    public Waveform process (Object input){
        return filter.process((Waveform)input);
    }
}
public class FilterProcess{
    public static void main(String[] args){
        Waveform w = new Waveform();
        Apply.process(new FilterAdapter(new LowPass(1.0)),w);
        Apply.process(new FilterAdapter(new HighPass(2.0)),w);
        Apply.process(new FilterAdapter(new BandPass(3.0,4.0)),w);
    }
}

9.4Java中的多重继承

  1. 注意一点implements关键字之后,可以继承多个接口,并可以向上转型为每个接口.

9.5通过继承来扩展接口

interface Monster{
    void mence();
}
interface DangeousMonster extends Monster{
    void destroy();
}

9.7接口中的域

  1. 接口中的域隐式地是static和final的

9.9接口与工厂(难点与重点)可以说是必知必会的东西

  1. 文字描述:接口时实现多重继承的途径,而生成遵循某个接口的对象的典型方式就是工厂方法设计模式.
  2. 这与直接调用构造器不同,我们在工厂对象上调用的是创建方法,而该工厂对象将生成接口的某个实现的对象.理论上,通过这种方式,我们的代码将完全与接口的实现分离,这就使得我们可以透明地将某个实现替换为另一个实现.
package cn.itcast.zhuofai730.demo9_9;

import java.util.ServiceConfigurationError;

import static cn.itcast.zhuofai730.util.Print.print;

interface Service{
    void method1();
    void method2();
}
interface ServiceFactory{
    Service getService();
}
class Implementation1 implements Service{
    Implementation1(){}//Package access
    public void method1(){print("Implementation1 method1");}
    public void method2(){
        print("Implementation method2");
    }
}
class Implementation1Factory implements ServiceFactory{
    public Service getService(){
        return new Implementation1();
    }
}
class Implementation2 implements Service{
    Implementation2(){}//Pakage access

    @Override
    public void method1() {
        print("Implementation2 method1");

    }

    @Override
    public void method2() {
        print("Implementation2 method2");
    }
}
class Implementation2Factory implements ServiceFactory{
    public Service getService(){
        return new Implementation2();
    }
}
public class Factories {
    public static void serviceConsumer(ServiceFactory fact){
        Service s = fact.getService();
        s.method1();
        s.method2();
    }

    public static void main(String[] args) {
        serviceConsumer(new Implementation1Factory());
        //Implementations are completely interchangeable;
        serviceConsumer(new Implementation2Factory());
    }
}

number two program

package cn.itcast.zhuofai730.demo9_9;


import static cn.itcast.zhuofai730.util.Print.print;

interface Game{boolean move();}
interface GameFactory {Game getGame();}
class Checkers implements Game{
    private int moves = 0;
    private static final int MOVES = 3;
    public boolean move(){
        print("Checker move" + moves);
        return ++moves != MOVES;
    }
}
class CheckersFactory implements GameFactory{
    public Game getGame(){
        return new Checkers();
    }
}
class Chess implements Game{
    private int moves = 0;
    private static final int MOVES = 4;
    public boolean move(){
        print("Chess move "+ moves);
        return ++moves != MOVES;
    }
}
class ChessFactory implements GameFactory{
    public Game getGame(){
        return new Chess();
    }
}

public class Games {
    public static void playGame(GameFactory factory){
        Game s = factory.getGame();
        while(s.move())
            ;
    }
    public static void main(String[] args) {
        playGame(new CheckersFactory());
        playGame(new ChessFactory());
    }
}

猜你喜欢

转载自blog.csdn.net/zhuofai_/article/details/82352627