6

Can anyone explain me how these two declaration differs from each other

public virtual interface MyInterface { }

and

public interface MyInterface { }

? what this virtual keyword makes difference here?

4 Answers 4

3

What Chiz has explained stands true for Classes. Interfaces are always abstract which means they will only contain abstract methods. In OOPL Virtual keyword is defined against a class to allow it's implementation class to override abstract methods. As every Interface has an implementation class, defining an Interface as 'Virtual' is optional to me.

4
  • The question is about virtual not abstract keyword. Commented Jan 11, 2015 at 5:06
  • @chiz The question is about virtual and also about Interfaces. And I didn't change my answer like you.
    – Jarvis
    Commented Jan 11, 2015 at 5:34
  • Virtual is not optional because interface has implementation class. I can create interface and no class will implement it. What is wrong with editing answer? Commented Jan 11, 2015 at 5:38
  • 1
    There is nothing wrong with edited answer but answer should have some relevance with your old answer. Your each answer is a total counter part of previous one. Its better to be specific with answer as it creates confusion in the mind of reader Commented Jan 12, 2015 at 10:10
8

Declaring a class or interface virtual allows the class or interface to be extended.

A virtual class may also declare methods virtual which allows them to be overridden.

public virtual class Player {
    String name;

    public Player(String name){
        this.name = name;
    }

    public String getName(){
        return this.Name;
    }

    public virtual String getGreeting(){
        return 'Are you ready to play, ' + this.getName() + '?';
    }
}

public class FootballPlayer extends Player {
     public FootballPlayer(String name){
         super(name);
     }

     public override String getGreeting(){
         return 'It\'s a great day for football, ' + this.getName() + '!';
     }
}


@isTest
public static void testPlayers(){
    Player p = new Player('Fred');
    System.assertEquals('Fred', p.getName());
    System.assertEquals('Are you ready to play, Fred?', p.getGreeting());

    FootballPlayer fp = new FootballPlayer('Fred');
    System.assertEquals('Fred', fp.getName());
    System.assertEquals('It\'s a great day for football, Fred!', fp.getGreeting());
}

When extending an interface there is no need to declare a method virtual since the methods are still to be defined.

public virtual interface Cleanable {
    void clean();
    Boolean getIsClean();
}

public interface Polishable extends Cleanable {
    void polish();
    Boolean getIsPolished();
}


public class Dishes implements Cleanable {
    Boolean isClean;

    public Dishes(){
        this.isClean = false;
    }

    public void clean(){
        this.isClean = true;
    }

    public Boolean getIsClean(){
        return this.isClean;
    }
}


public class Silverware implements Polishable {
    Boolean isClean;
    Boolean isPolished;

    public Silverware(){
        this.isClean = false;
        this.isPolished = false;
    }

    public void clean(){
        this.isClean = true;
    }

    public void polish(){
        this.clean();
        this.isPolished = true;
    }

    public Boolean getIsClean(){
        return this.isClean;
    }

    public Boolean getIsPolished(){
        return this.isPolished;
    }
}


@isTest
public static void testCleaningTheKitchen(){
    List<Cleanable> cleanableList = new List<Cleanable>();
    cleanableList.add(new Dishes());
    Silverware sw = new Silverware();
    cleanableList.add(sw);

    for(Cleanable c :cleanableList){
        c.clean();
        System.assertEquals(true, c.getIsClean());
    }

    System.assertEquals(false, sw.getIsPolished());

     sw.polish();

    System.assertEquals(true, sw.getIsPolished());
}

Update:

I've discovered that in interfaces, the virtual modifier isn't necessary. Interfaces can be extended without the parent interface being declared virtual. Also, when extending interfaces, it's possible to add methods already declared by a parent because the methods haven't been defined by the implementation yet, so there's no defined function to override. The following code compiles:

public interface Cleanable {
    void clean();
    Boolean getIsClean();
}

public interface Polishable extends Cleanable {
    void polish();
    Boolean getIsPolished();
    Boolean getIsClean();
}

public interface Buffable extends Polishable {
    void buff();
    Boolean getIsBuffed();
    Boolean getIsClean();
}

public class HardwoodFloor implements Buffable {
    Boolean isClean, isPolished, isBuffed;

    public HardwoodFloor(){
        this.isClean = false;
        this.isPolished = false;
        this.isBuffed = false;
    }

    public Boolean getIsClean(){
        return this.isClean;
    }

    public Boolean getIsPolished(){
        return this.isPolished;
    }

    public Boolean getIsBuffed(){
        return this.isBuffed;
    }

    public void clean(){
        this.isClean = true;
    }

    public void polish(){
        this.isPolished = true;
    }

    public void buff(){
        this.isBuffed = true;
    }

}
10
  • your code has many syntax errors! so have to correct it first and then understand it!! Commented Jan 7, 2015 at 13:39
  • the code's cleaned up and compiles Commented Jan 7, 2015 at 15:33
  • "Declaring a class or interface virtual allows the class or interface to be extended." This sounds good in case of class but interface are meant to be overridden as they are 100 % abstract class. It serves no purpose if can not be overridden. Cleanable interface in your above code can be overridden even if I declare it without any virtual keyword Commented Jan 8, 2015 at 13:53
  • Yes, concerning interfaces, the virtual keyword doesn't really do anything. If I remove virtual from the Cleanable interface, everything still complies. When extending an interface, I can re-declare a method from a parent without using override because there is no method to override yet. Commented Jan 8, 2015 at 15:05
  • I find your explanation misleading!!!Your explanation - " When extending an interface, I can re-declare a method from a parent without using override". We never use override keyword while implementing interface's method! It will give you compile error.The reason being if we are implementing the interface then it is must to override. We use it in context of extending a class where overriding the inherited method is optional. Please correct if I've misunderstood your explanation. Commented Jan 9, 2015 at 9:35
4

As it appeared, in example by AmatorVitae, interfaces are by default, wether you put virtual or not. Like private access modifier, wether you put it or not, it is private. Thanks for the question.

I leave my original answer.

As for example, virtual keyword shows that interface can be extended. You are not able to extend interface (or a class) if it isnt defined with virtual keyword.

In case of interface, class must override methods. In case of virtual it gives an option to override or use ancestor's implementation.

The virtual definition modifier declares that this class allows extension and overrides. You cannot override a method with the override keyword unless the class has been defined as virtual.

Apex class definition

2
public virtual interface DemoInterface
{
         void go();
}

This code works fine if i write it inside in any apex class in org. But when I write this in developer console i get an error message as "Type is virtual by default in this context" This suggest that virtual is default keyword for interface!So specifying virtual keyword for it is redundant.

3
  • 1
    Exactly, it's redundant to use virtual keyword against an Interface as they are always implemented(extended)
    – Jarvis
    Commented Jan 11, 2015 at 5:46
  • I observed one thing later! The message "Type is virtual by default in this context" comes every time I try to execute a class using virtual keyword in developer console !! Commented Feb 3, 2015 at 8:03
  • 1
    Are you executing your class in Anonymous window? If yes, when you define a class in an anonymous block, the class is considered virtual by default when the anonymous block executes.
    – Jarvis
    Commented Feb 3, 2015 at 10:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .