What Are Virtual Methods

What is the difference between an abstract method and a virtual method?

An abstract function cannot have functionality. You're basically saying, any child class MUST give their own version of this method, however it's too general to even try to implement in the parent class.

A virtual function, is basically saying look, here's the functionality that may or may not be good enough for the child class. So if it is good enough, use this method, if not, then override me, and provide your own functionality.

When is it appropriate to use virtual methods?

When you design a class you should have a pretty good idea as to whether it represents an interface (in which case you mark the appropriate overrideable methods and destructor virtual) OR it's intended to be used as-is, possibly composing or composed with other objects.

In other words your intent for the class should be your guide. Making everything virtual is often overkill and sometimes misleading regarding which methods are intended to support runtime polymorphism.

Why do we need virtual functions in C++?

Without "virtual" you get "early binding". Which implementation of the method is used gets decided at compile time based on the type of the pointer that you call through.

With "virtual" you get "late binding". Which implementation of the method is used gets decided at run time based on the type of the pointed-to object - what it was originally constructed as. This is not necessarily what you'd think based on the type of the pointer that points to that object.

class Base
{
public:
void Method1 () { std::cout << "Base::Method1" << std::endl; }
virtual void Method2 () { std::cout << "Base::Method2" << std::endl; }
};

class Derived : public Base
{
public:
void Method1 () { std::cout << "Derived::Method1" << std::endl; }
void Method2 () { std::cout << "Derived::Method2" << std::endl; }
};

Base* basePtr = new Derived ();
// Note - constructed as Derived, but pointer stored as Base*

basePtr->Method1 (); // Prints "Base::Method1"
basePtr->Method2 (); // Prints "Derived::Method2"

EDIT - see this question.

Also - this tutorial covers early and late binding in C++.

Difference between virtual and abstract methods

Virtual methods have an implementation and provide the derived classes with the option of overriding it. Abstract methods do not provide an implementation and force the derived classes to override the method.

So, abstract methods have no actual code in them, and (non-abstract) subclasses HAVE TO override the method. Virtual methods can have code, which is usually a default implementation of something, and any subclasses CAN override the method using the override modifier and provide a custom implementation.

public abstract class E
{
public abstract void AbstractMethod(int i);

public virtual void VirtualMethod(int i)
{
// Default implementation which can be overridden by subclasses.
}
}

public class D : E
{
public override void AbstractMethod(int i)
{
// You HAVE to override this method
}
public override void VirtualMethod(int i)
{
// You are allowed to override this method.
}
}

Java - Virtual Methods

Yes, virtual methods are treated differently by the compiler and the runtime. The JVM specifically utilizes a virtual method table for virtual method dispatch:

An object's dispatch table will
contain the addresses of the object's
dynamically bound methods. Method
calls are performed by fetching the
method's address from the object's
dispatch table. The dispatch table is
the same for all objects belonging to
the same class, and is therefore
typically shared between them. Objects
belonging to type-compatible classes
(for example siblings in an
inheritance hierarchy) will have
dispatch tables with the same layout:
the address of a given method will
appear at the same offset for all
type-compatible classes. Thus,
fetching the method's address from a
given dispatch table offset will get
the method corresponding to the
object's actual class.

Why use virtual functions?

You use virtual functions when you want to override a certain behavior (read method) for your derived class rather than the one implemented for the base class and you want to do so at run-time through a pointer to the base class.

The classic example is when you have a base class called Shape and concrete shapes (classes) that derive from it. Each concrete class overrides (implements a virtual method) called Draw().

The class hierarchy is as follows:

Class hierarchy

The following snippet shows the usage of the example; it creates an array of Shape class pointers wherein each points to a distinct derived class object. At run-time, invoking the Draw() method results in the calling of the method overridden by that derived class and the particular Shape is drawn (or rendered).

Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();

The above program just uses the pointer to the base class to store addresses of the derived class objects. This provides a loose coupling because the program does not have to change drastically if a new concrete derived class of shape is added anytime. The reason is that there are minimal code segments that actually use (depend) on the concrete Shape type.

The above is a good example of the Open Closed Principle of the famous SOLID design principles.

What's the difference between a setter method and a virtual method (in Ruby)?

Somewhere I picked up the notion that a setter notion is also a virtual method, i.e., they're synonyms.

That is a logical error: a Dog is also a Mammal, but that does not mean that they are synonyms.

Likewise, in Ruby, setter methods are also virtual methods (because in Ruby all methods are virtual), but they are not synonyms. Since there are only virtual methods in Ruby, you could just as well say: setter methods are also methods. Now, it should become obvious that this does not necessarily mean that methods are also setter methods, right?

Wikipedia says this about virtual methods:

In object-oriented programming, in languages such as C++, a virtual
function or virtual method is an inheritable and overridable function
or method for which dynamic dispatch is facilitated.

The term makes no sense in Ruby, because in Ruby, all methods are virtual, so there is no need to distinguish virtual from non-virtual methods.

In OOP in general, the term "virtual" applies to language-"things" that are dispatched dynamically (i.e. at runtime) and can be overridden.

class Foo
def to_s
foo
end

def foo
'Foo'
end
end

class Bar < Foo
def foo
'Bar'
end
end

Bar.new.to_s
#=> 'Bar'

As you can see, Bar.new.to_s returns the string 'Bar', even though to_s is defined in Foo and simply calls foo. However, even though to_s is defined in Foo, it does not call Foo's foo, it calls Bar's foo, because the object in question has class Bar. Bar has overridden the definition of foo with its own, and the call was dispatched dynamically to whatever class the current object has.

Alan Kay, who coined the term "object oriented" used a messaging metaphor, that IMHO makes things like this much easier to understand: objects communicate with each other by sending messages. And it works just like when you send someone a message in the real world: you can't know what the receiver does with the message, all you can observe is the response you get. And when you send someone a message, then they will interpret the request in the message according to their own knowledge.

So, if you imagine this exchange between you and your friend:

  1. You send the message "convert yourself to a string" to a friend.
  2. Your friend doesn't know what that means, so he asks his superior, and he tells him, it means "send yourself the message 'foo'".
  3. Your friend sends himself the message "foo".
  4. Your friend has his own idea of what "foo" means, so he doesn't need to look it up.

Other languages have other virtual "things", e.g. Newspeak has virtual superclasses.

So, if I have this:

class Foo < Array
# … stuff
end

class Bar
def Array
return SomeClassLikeArray
end

def bar
Foo.new
end
end

Bar.new.bar
# this will be a `Foo` which has `SomeClassLikeArray` as its superclass

I do have a little better notion of what setter methods are. I've been thinking that it is just any method that sets the value of an instance variable.

Yes and no.

It is a method that appears to set an instance variable. You don't actually know what that method does. (Remember the messaging metaphor: you can only observe your friend's response, you don't know what your friend actually does with the message!)

For example, in a web framework, a setter method may actually write to the database instead of setting an instance variable.

At a more technical note, in general, in Ruby, a setter method is a method whose name ends with =.

So attr_writer :foo is a setter method,

No, that's not a setter method. It creates a setter method named foo=.

and maybe a method external to a class that changes the value of foo would also be a setter method. Is that right?

That's not what we generally call a setter method. It's also simply not possible in Ruby, since only the object itself has access to its instance variables.

And even in languages that allow it, it is bad design: objects should do stuff, not store stuff. It is about behavior. You should tell objects to perform actions.

But that's not what "virtual method" means, is it? So basically, I'm looking for an explanation of the differences and I can't find any (or, not that I can understand).

It doesn't really make sense to talk about their differences since the two concepts are completely orthogonal; they don't have anything to do with each other.

A virtual method is a method that can be overridden. A setter method is a method that sets stuff. You can have a setter method that can be overridden, a setter method that cannot be overridden, a non-setter method that can be overridden, and a non-setter method that cannot be overridden.

Specifically in Ruby, all methods are virtual, so all setter methods are virtual (because all setter methods are methods), but that's it.

It's also the case, isn't it, that a so-called "factory method" could be described as method to create an object of a particular type, as specified by a collection of setter methods, from outside of the class (i.e., the code defining the class)?

So, there is a Design Pattern called Factory Method, but you are talking about the more general concept of a method that creates objects.

Yes, a method that creates objects is sometimes called "Factory Method". In Ruby, the most widely-used factory method is new, which looks something like this:

class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
return obj
end
end

Actually, initialize is a private method, so we need to use reflection to circumvent the access protection, but that doesn't change the gist of the method:

class Class
def new(*args, &block)
obj = allocate
obj.__send__(:initialize, *args, &block)
return obj
end
end

Can you write virtual functions / methods in Java?

From wikipedia

In Java, all non-static methods are by
default "virtual functions." Only
methods marked with the keyword final,
which cannot be overridden, along with
private methods, which are not
inherited, are non-virtual.



Related Topics



Leave a reply



Submit