Newer Version Available
Extended Class Example
The following is an extended example of a class, showing all the features of Apex classes. The keywords and concepts introduced in the example are explained in more detail throughout this chapter.
1// Top-level (outer) class must be public or global (usually public unless they contain
2// a Web Service, then they must be global)
3public class OuterClass {
4
5 // Static final variable (constant) – outer class level only
6 private static final Integer MY_INT;
7
8 // Non-final static variable - use this to communicate state across triggers
9 // within a single request)
10 public static String sharedState;
11
12 // Static method - outer class level only
13 public static Integer getInt() { return MY_INT; }
14
15 // Static initialization (can be included where the variable is defined)
16 static {
17 MY_INT = 2;
18 }
19
20 // Member variable for outer class
21 private final String m;
22
23 // Instance initialization block - can be done where the variable is declared,
24 // or in a constructor
25 {
26 m = 'a';
27 }
28
29 // Because no constructor is explicitly defined in this outer class, an implicit,
30 // no-argument, public constructor exists
31
32 // Inner interface
33 public virtual interface MyInterface {
34
35 // No access modifier is necessary for interface methods - these are always
36 // public or global depending on the interface visibility
37 void myMethod();
38 }
39
40 // Interface extension
41 interface MySecondInterface extends MyInterface {
42 Integer method2(Integer i);
43 }
44
45 // Inner class - because it is virtual it can be extended.
46 // This class implements an interface that, in turn, extends another interface.
47 // Consequently the class must implement all methods.
48 public virtual class InnerClass implements MySecondInterface {
49
50 // Inner member variables
51 private final String s;
52 private final String s2;
53
54 // Inner instance initialization block (this code could be located above)
55 {
56 this.s = 'x';
57 }
58
59 // Inline initialization (happens after the block above executes)
60 private final Integer i = s.length();
61
62 // Explicit no argument constructor
63 InnerClass() {
64 // This invokes another constructor that is defined later
65 this('none');
66 }
67
68 // Constructor that assigns a final variable value
69 public InnerClass(String s2) {
70 this.s2 = s2;
71 }
72
73 // Instance method that implements a method from MyInterface.
74 // Because it is declared virtual it can be overridden by a subclass.
75 public virtual void myMethod() { /* does nothing */ }
76
77 // Implementation of the second interface method above.
78 // This method references member variables (with and without the "this" prefix)
79 public Integer method2(Integer i) { return this.i + s.length(); }
80 }
81
82 // Abstract class (that subclasses the class above). No constructor is needed since
83 // parent class has a no-argument constructor
84 public abstract class AbstractChildClass extends InnerClass {
85
86 // Override the parent class method with this signature.
87 // Must use the override keyword
88 public override void myMethod() { /* do something else */ }
89
90 // Same name as parent class method, but different signature.
91 // This is a different method (displaying polymorphism) so it does not need
92 // to use the override keyword
93 protected void method2() {}
94
95 // Abstract method - subclasses of this class must implement this method
96 abstract Integer abstractMethod();
97 }
98
99 // Complete the abstract class by implementing its abstract method
100 public class ConcreteChildClass extends AbstractChildClass {
101 // Here we expand the visibility of the parent method - note that visibility
102 // cannot be restricted by a sub-class
103 public override Integer abstractMethod() { return 5; }
104 }
105
106 // A second sub-class of the original InnerClass
107 public class AnotherChildClass extends InnerClass {
108 AnotherChildClass(String s) {
109 // Explicitly invoke a different super constructor than one with no arguments
110 super(s);
111 }
112 }
113
114 // Exception inner class
115 public virtual class MyException extends Exception {
116 // Exception class member variable
117 public Double d;
118
119 // Exception class constructor
120 MyException(Double d) {
121 this.d = d;
122 }
123
124 // Exception class method, marked as protected
125 protected void doIt() {}
126 }
127
128 // Exception classes can be abstract and implement interfaces
129 public abstract class MySecondException extends Exception implements MyInterface {
130 }
131}This code example illustrates:
- A top-level class definition (also called an outer class)
- Static variables and static methods in the top-level class, as well as static initialization code blocks
- Member variables and methods for the top-level class
- Classes with no user-defined constructor — these have an implicit, no-argument constructor
- An interface definition in the top-level class
- An interface that extends another interface
- Inner class definitions (one level deep) within a top-level class
- A class that implements an interface (and, therefore, its associated sub-interface) by implementing public versions of the method signatures
- An inner class constructor definition and invocation
- An inner class member variable and a reference to it using the this keyword (with no arguments)
- An inner class constructor that uses the this keyword (with arguments) to invoke a different constructor
- Initialization code outside of constructors — both where variables are defined, as well as with anonymous blocks in curly braces ({}). Note that these execute with every construction in the order they appear in the file, as with Java.
- Class extension and an abstract class
- Methods that override base class methods (which must be declared virtual)
- The override keyword for methods that override subclass methods
- Abstract methods and their implementation by concrete sub-classes
- The protected access modifier
- Exceptions as first class objects with members, methods, and constructors
This example shows how the class above can be called by other Apex code:
1// Construct an instance of an inner concrete class, with a user-defined constructor
2OuterClass.InnerClass ic = new OuterClass.InnerClass('x');
3
4// Call user-defined methods in the class
5System.assertEquals(2, ic.method2(1));
6
7// Define a variable with an interface data type, and assign it a value that is of
8// a type that implements that interface
9OuterClass.MyInterface mi = ic;
10
11// Use instanceof and casting as usual
12OuterClass.InnerClass ic2 = mi instanceof OuterClass.InnerClass ?
13 (OuterClass.InnerClass)mi : null;
14System.assert(ic2 != null);
15
16// Construct the outer type
17OuterClass o = new OuterClass();
18System.assertEquals(2, OuterClass.getInt());
19
20// Construct instances of abstract class children
21System.assertEquals(5, new OuterClass.ConcreteChildClass().abstractMethod());
22
23// Illegal - cannot construct an abstract class
24// new OuterClass.AbstractChildClass();
25
26// Illegal – cannot access a static method through an instance
27// o.getInt();
28
29// Illegal - cannot call protected method externally
30// new OuterClass.ConcreteChildClass().method2();This code example illustrates:
- Construction of the outer class
- Construction of an inner class and the declaration of an inner interface type
- A variable declared as an interface type can be assigned an instance of a class that implements that interface
- Casting an interface variable to be a class type that implements that interface (after verifying this using the instanceof operator)