如何将Java接口代码移植到C ++抽象基类中?

时间:2010-10-08 04:29:01

标签: java c++ design-patterns oop

我是OOP编程和C ++的新手,我目前正在学习设计模式。

只需抓住Head First Design Patterns一书即可学习。它实际上很棒,我已经掌握了基本概念。第一章讨论了编程到接口而不是实现。不幸的是,这些例子使用的是java。

下面是使用“界面”的书中的java代码示例,据我所知,这不能直接在C ++中移植。我试图实现C ++的抽象基类。但是我特意在动态设置QuackBehavior时丢失了。

C ++虚拟函数定义可以动态吗?有人可以告诉我如何将这个Java代码移植到C ++中的最佳方法吗?我需要这个以确保我在学习OOP的正确轨道上。谢谢!

//FlyBehavior.java
public interface FlyBehavior{
    public void fly(); //the interface that all flying behavior classes implement
}


public class FlyWithWings implements FlyBehavior {
    public void fly(){
        System.out.println("Im flying!"); //flying behavior implementation for ducks that do fly
    }
}

//QuackBehavior.java
public interface QuackBehavior{
    public void quack();
}

public class Quack implements QuackBehavior {
    public void quack() {
        System.out.println("Quack");
    }
}

public class Squeak implements QuackBehavior {
    public void quack() {
        System.out.println("Squeak");
    }
}

public class MuteQuack implements QuackBehavior {
    public void quack() {
        System.out.println("<<SILENCE>>");
    }
}



//duck.java
public abstract class Duck{
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public Duck(){
    }

    public abstract void display();

    public void performFly(){
        flyBehavior.fly();
    }

    public void performQuack(){
        quackBehavior.quack();
    }

    public void setFlyBehavior(FlyBehavior fb){
        flyBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior qb){
        quackBehavior = qb;
    }

    public void swim(){
        System.out.println ("All duck float, even decoys");
    }
}


//MallardDuck.java
public class MallardDuck extends Duck{
    public MallardDuck(){
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }

    public void display(){
        System.out.println("Im a real Mallard duck");
    }
}

//miniducksim.java
public class MiniDuckSimulator{
    public static void main (String[] args){
        Duck mallard = new MallardDuck();

        mallard.setQuackBehavior(new Squeak()); // this is where im lost
                                                //how can definition of a virtual functions in C++ be dynamic?

        mallard.performQuack();
        mallard.performFly();
    }
}

4 个答案:

答案 0 :(得分:1)

C++ code sample for head-first

对于Java或C#版本,请检查网站headfirstlabs.com

答案 1 :(得分:1)

如果Quack()方法在抽象基类QuackBehavior中声明为纯虚拟,那么事情应该没问题。

在方法SetQuackBehavior()中需要一个基类引用,它显然可以容纳任何派生类对象。可以在C ++中应用相同的内容,在QuackBehavior方法中使用指向SetQuackBehavior()类的指针,然后将Squeak类对象的地址传递给它。现在,当通过基类指针在quack()中调用PerformQuack()方法时,它将调用派生类的适当具体方法,在这种情况下为Squeak

答案 2 :(得分:1)

Dang - 应该知道头头第一团伙会把它移走。无论如何,这是一个解决方案:

   // HeadFirst.cpp : Defines the entry point for the console application.
   //

   #include "stdafx.h"

   class QuackBehavior
   {
   public:
      virtual void quack() = NULL;
   };

   class Quack : public QuackBehavior
   {
   public:
      void quack()
      {
         printf("Quack");
      }
   };

   class Squeak : public QuackBehavior
   {
   public:
      void quack()
      {
         printf("Squeak");
      }
   };

   class Duck
   {
   public:
      QuackBehavior *pQuack;

      void performQuack()
      {
         if (pQuack!=NULL)
            pQuack->quack();
      }

      void setQuackBehavior(QuackBehavior *qb)
      {
         pQuack = qb;
      }
   };

   class MallardDuck : public Duck
   {
   public:
      MallardDuck()
      {
         pQuack = new Quack();
      }
   };

   int _tmain(int argc, _TCHAR* argv[])
   {
      Duck *mallard = new MallardDuck();
      mallard->setQuackBehavior(new Squeak());
      mallard->performQuack();
   return 0;
   }

答案 3 :(得分:0)

这是一个粗略翻译 - 只是被警告说这打击我作为C ++的惯用(或好)使用:

#include <iostream>

struct FlyBehavior {
    virtual void operator()() const = 0; 
};

struct FlyWithWings: FlyBehavior {
    virtual void operator()() const { std::cout << "I'm flying!\n"; }
};

struct QuackBehavior {
    virtual void operator()() const = 0;
};

struct Quack : QuackBehavior {
    virtual void operator()() const { std::cout << "Quack\n"; }
};

struct Squeak : QuackBehavior {
    virtual void operator()() const { std::cout << "Squeak\n"; }
};

struct MuteQuack : QuackBehavior {
    virtual void operator()() const { std::cout << ("<<SILENCE>>\n"); }
};

class Duck {
    FlyBehavior const *flyBehavior;
    QuackBehavior const *quackBehavior;
public:
    Duck(FlyBehavior const *f, QuackBehavior const *q) :
        flyBehavior(f), quackBehavior(q)
    {}

    void setQuackBehavior(QuackBehavior *q) { quackBehavior = q; }
    void setFlyBehavior(FlyBehavior *f) { flyBehavior = f; }
    virtual void display() const = 0;
    void fly() const { (*flyBehavior)(); }
    void quack() const { (*quackBehavior)(); }
    void swim() const { std::cout << "All ducks float, even decoys\n"; }
};

struct MallardDuck : Duck {
    MallardDuck() : Duck(&FlyWithWings(), &Quack()) { }
    virtual void display() const { std::cout << "I'm a real Mallard duck\n"; }
};

int main() {
    MallardDuck mallard;
    mallard.setQuackBehavior(&Squeak());
    mallard.quack();
    mallard.fly();
    return 0;
}