Disclaimer: Translating Java code/patterns/best practices directly to C++ leads you to a world of pain.
Java has interfaces. What comes closest to that in C++ is an abstract base class:
struct Animal {
    virtual void makeSound() const = 0;   // <- pure virtual, ie no implementation in Animal
    virtual ~Animal() = default;
};
struct Dog : Animal {
    void bark() const { std::cout << "Moo"; }
    void makeSound() const override {  bark(); }
};
//programming to implementation
Dog d;                            // C++ has values, not everything is a reference like in Java
d.bark();
//programming to an interface/supertype (here Animal)
std::shared_ptr<Animal> animal = std::make_shared<Dog>();  // Use smart pointers, not raw ones
                                                           // and don't use new in C++
animal->makeSound();
Whether you could do this also with templates is difficult / impossible to answer, because this is nothing more than an example to illustrate the use of an interface / abstract base class and thats the only requirement.
As has been pointed out in a comment, patterns do not exist for their own sake, but to aid development. Once you tackle real problems and you have some familiarity with patterns you will notice when a certain problem requires the use of a pattern.