Hi I'm just confused on how to to use Abstract class and Virtual. Can't seem to find any difference between them and what are some scenarios where in it's applicable to use abstract or virtual.
5 Answers
tl;dr:
Practically speaking, there isn't much difference. Don't worry about it too much. I tend to use abstract
more often.
long version
The difference has historically been quite subtle.
- Both
virtual
andabtract
classes allow you to extend the class (i.e. create child classes that inherit non-private methods and variables) - A
virtual
class can be instantiated directly, whereas anabstract
class cannot - Both
virtual
andabstract
classes can containvirtual
methods (virtual
methods can have a default implementation that is inherited by child classes, whereasabstract
methods can only be signatures, and must be implemented in child classes) - Only
abstract
classes may containabstract
methods
In practice, I haven't seen much practical difference between the two. The abstract
and virtual
modifiers, in my mind, are more important for methods (as opposed to classes).
If you're going to use a class that's either abstract
or virtual
, I've found that I'm more likely to be using that class as more of a contract (i.e. when you use this class, we guarantee that variables a
, b
, and c
will be available for use, along with methods x
, y
, and z
), rather than a specialization that is used apart, distinctly, from its parent class.
This mostly comes down to the philosophy of object-oriented design that I have learned as part of my professional career. To put it into a single sentence: If you're relying on something having a specific implementation (i.e. you need to use a square
or a rectangle
instead of a more general parallelogram
), then you can probably improve your solution.
The general idea is that by relying on contracts rather than implementations, your code is more resistant to change. Put another way, by relying on contracts, a change to a specific implementation of that contract is contained to one or two classes (as opposed to making a change in one class ending up requiring a change to many other classes).
So for that goal (relying on a contract more than an implementation), I find myself using abstract
classes more often because I tend to want the consumers of my code to use specific, specialized implementations (to suit the task at hand) rather than a general "catch-all" implementation. To that end, abstract
, with it's inability to be directly constructed, is more useful to me.
-
12"Both virtual and abstract classes can contain virtual or abstract methods" -- Nope, only abstract classes can contain abstract methods. The point of a virtual class is that it can operate without requiring subclassing.– sfdcfox ♦Commented Feb 25, 2018 at 20:31
-
Abstract classes allow you to define "partial" classes. They implement some sort of algorithm that can be used by other classes, but do not represent a full implementation by themselves. For example, my AWS example provides a class that handles calculating parameters, etc (over 200 lines of default functionality), but does not directly do anything with AWS; the remainder is handled by child classes to connect to a specific service. Note that abstract classes could be implemented by interfaces or helper classes, but make the code more compact and generally legible.
Virtual classes allow you to define "full" classes. They implement all of the necessary functionality to operate on their own, but can be extended by child classes in order to allow customization of its behavior. This is far less common in every day Apex Code than abstract classes, but is useful when you have large classes that provide tons of default functionality, but may require overriding just one or two methods. In Java, these are used all over the place, for example, a WindowAdapter that can listen to about a dozen events, but can have just one method overridden so the developer doesn't have to write implementations for all of the methods.
Unlike interfaces and abstract methods, virtual classes allow you to override just one single method if you want, without having to implement all of the methods. For example, a Trigger Handler factory might use a virtual class to provide default methods (e.g. beforeInsert, afterInsert, beforeUpdate...), but allow the developer to override just one method instead of a dozen.
-
Thank you for the example. Really helped a lot, things are getting clearer now.– imajmdfCommented Feb 25, 2018 at 20:53
-
1If you want to do true unit testing on a class basis, rather than heavier tests that are more like integration tests (depending on other classes to do a lot of work), you might like to make the majority of your classes virtual and use virtual methods instead of static ones. That way, with an appropriate dependency injection mechanism (quite possible in Apex), you can isolate the class to be tested from other classes by mocking out those other classes (essentially overriding the various methods in the dependency classes).– Phil WCommented Mar 25, 2019 at 15:01
The Apex Class Definition resource from the Apex Developer Guide may provide some illumination.
In summary, virtual
classes permits subclassing and method overriding. However, a virtual
class does implement functionality itself and can be instantiated and used directly.
Conversely, abstract
classes must be subclassed and have methods overridden to provide functionality. abstract
classes cannot be instantiated or used themselves; they are more fully "abstract base classes".
I see that is quite an old thread, but I have some brief descriptions, which can be helpful for future use.
Interface
- To create an interface we need to use interface keyword.
- Interface can provide a layer of abstraction to your code.
- Interface is an apex the class that can contain only method signature, as a result, the body of each method must be empty.
- An apex class that is using the interface must implement all methods listed in the interface.
- Interface separates the specific method declaration from its implementation. Therefore you can have different implementations for the same method. The concept behind Interface is that you can change the implementation without changing your whole code. Consequently, the method signature (return type, parameters) is always the same.
- Interface can be treated as a new data type. In Apex we have a few predefined interfaces like String, Integer, Double, etc. In other words implementation of those methods can be changed (by Salesforce) without changes in our code – that’s the power of interface! e.g.: String.isBlank(‘Test’); We know method signature (public static Boolean isBlank(String inputString)), but we don’t know implementation layer.
Abstract
- To create an abstract class, we need to use an abstract definition modifier.
- Allow extending the child's class.
- Abstract class can contain methods signed as abstract, to clarify, it is a method that has only a signature (body is not defined).
- Child class must implement all methods declared as abstract!
- Abstract class can also include other methods, which have logic. To allow child class access those methods use protected or public keywords.
- Cannot be initialize directly: new TestAbstractClass();
- Abstract class can contain both virtual and abstract methods.
- Abstract class is some kind of “partial” class. Therefore, some methods are implemented, and some needs to be implemented by the child class.
- virtual methods can be overridden, but this is not mandatory.
Virtual
- To create a virtual class, we need to use a virtual definition modifier.
- You can extend a class to provide more sophisticated behavior.
- Class that extends another class inherits all the methods and properties of the extended class.
- Methods declared as virtual can be overridden. In other words, overriding a virtual method allows you to provide a different implementation for an existing method.
- A class can only extend one other class, but it can implement more than one interface.
- Virtual class can be initialize directly new TestVirtualClass();
- You can use virtual or regular methods.
- Virtual class is some kind of “full” class. All methods are implemented but can be overridden by the child class.
Feature | Interface | Abstract | Virtual |
---|---|---|---|
Keyword | interface e.g public interface MyInterface {} |
abstract e.g public abstract class MyAbstractClass {} |
virtual e.g public virtual class MyVirtualClass {} |
How to use? | By implements e.g public class MyChildClass implements MyInterface {} |
By extends e.g public class MyChildClass extends MyAbstractClass {} |
By extends e.g public class MyChildClass extends MyVirtualClass {} |
Type of Methods | Only method signature e.g String getFullName(String firstName, String lastName); |
Can contains abstract , virtual and implements own methods. e.g abstract String getFullName(String firstName, String lastName); public virtual String getFullName(String firstName, String lastName); |
Can contains only virual and implements onw methods e.g public virtual String getFullName(String firstName, String lastName); |
Implement Parent Mehthods | ✅ All interface's methods needs to be implemented | ✅ Only methods signed as abstract |
❌ Cannot force child class to implements parent methods |
Override Parent Methods | ❌ Interface doesn't contain logic to override | ✅ Only methods signed as virtual |
✅ Only methods signed as virtual |
Has basic logic? | ❌ Interface contains only method signature | ✅ Methods signed as virual and inner methods can contain basic logic |
✅ Methods signed as virual and inner methods can contain basic logic |
Can be initialized directly? | ❌ |
❌ |
✅ new MyVirtualClass(); |
Pros | ✅ New layer of abstraction. ✅ Interface can be treated as a new data type. ✅ Logic behind the interface can be changed without changes in related classes. ✅ We program to interfaces, not implementations. Code doesn't have reference to specific classes. ✅ Child class is forced to implement the interface's method (Guarantee specific logic). ✅ Child class can implement many interfaces. |
✅ Abstract class can store common logic (avoid redundancy) ✅ Child class can be forced to implement some (signed as abstract ) methods. ✅ Child class can override some (signed as virtual ) methods. ✅ Basic logic can be provided by abstract class inner methods. ( private , protected , public ) ✅ Easy to update common code for all child methods. Just update code in abstract class. |
✅ virtual class can be treated as a base class with base logic, which should be accessed by all child classes. ✅ Virtual class can be initialized direct ✅ Child class can override some (signed as virtual methods) ✅ Easy to update common code for all child method. Just update code in a virtual class. Basic logic can be provided by abstract class inner methods. ( private , protected , public ) |
Cons | ❌ Hard to add or change the interface's methods, because all classes that implement the interface need to be changed as well. ❌ Apex class needs to implement all interface methods even if it's not relevant. |
❌ Cannot be initialized directly. ❌ Apex class needs to implement all abstract methods even if it's not relevant. ❌ Child class can be only extended by one parent class. |
❌ Cannot force child class to implement parent method (abstract cannot be used) ❌ Child class can be only extended by one parent class. |
Goal | To create a new layer of abstraction | To provide a kind of "partial" class with common logic | To provide a kind of "full" class with base logic |
More details, examples of usage, and use cases can find https://beyondthecloud.dev/blog/abstract-virtual-interface-in-apex
-
Piotr, that's a very helpful summary and table. However it would make more sense for your example method to be named setFullNane instead of getFullName. The later would not want a first name and last name as an input, since it would be a method to return those values. A setFullName would need those input parameters and would have a void return type. Commented Jul 8 at 15:06
This is the Explaining like i am Ten Years old version of these concepts:
Imagine you have a recipe for a cake.
Recipe: This is like a class in programming. It tells you what ingredients to use and how to make the cake.
Chocolate Cake: This is like a derived class or subclass. It's a specific type of cake that follows the general recipe but has its own special ingredients and instructions for making it chocolate.
Now, let's talk about the keywords:
virtual: This is like saying, "You can change how this part of the recipe works." For example, you could change the frosting recipe or add a different filling to the cake.
abstract: This is like saying, "This part of the recipe is important, but I don't know exactly how to do it yet." For example, you might know that the cake needs to be baked, but you don't know the exact temperature or time.
interface: This is like a list of rules for all cakes. It says that all cakes must have a crust, filling, and frosting, but it doesn't tell you what those should be. Different types of cakes can follow these rules but have their own unique flavors and designs.
In simple terms:
virtual: Allows for different ways of doing things.
abstract: Defines a general idea but doesn't give specific details.
interface: Sets a standard for what something should be but doesn't tell you how to make it.