Abstract modifier

The abstract modifier indicates that a type is intended only to be a base type of other types. Typically, an abstract type does not provide implementations, which contain code to perform the function, for some or all of its functions and properties. This modifier applies to classes, interfaces, functions, and properties.

For example, the following code is a simple abstract class:

abstract class Vehicle {
}

If a type is specified as abstract, Gosu code cannot construct an instance of that type. For example, you cannot use code such as new MyType() for an abstract type. You can instantiate a subtype of the abstract type if the subtype fully implements all abstract members (functions and properties). A subtype that contains implementations for all abstract members of its supertype is called a concrete type.

For example, if class A is abstract and defines one method’s parameters and return value but does not provide code for the method, that method would be declared abstract. Another class B could extend A and provide code to implement that abstract method. Class A is the abstract class and class B is a concrete subclass of A.

For example, the following code defines an abstract Gosu class called Vehicle, which contains members but no abstract members:

package com.mycompany

abstract class Vehicle {
  var _name : String as Name
}

You cannot construct an instance of this class, but you can define another class that extends the class:

package com.mycompany

class Truck extends Vehicle {

   // The subtype can add its own members.
  var _TruckLength : int as TruckLength
}

You can now use code such as the following to create an instance of Truck:

var t = new Truck()

Things work differently if the supertype, in this case, Vehicle, defines abstract members. If the supertype defines abstract methods or abstract properties, the subtype must define a concrete implementation of each abstract method or property to support instantiation of the subclass. A concrete method implementation must implement actual behavior, not just inherit the method signature. A concrete property implementation must implement actual behavior of getting and setting the property, not just inherit the property name.

The subtype must implement an abstract function or abstract property using the same name as the supertype. Use the override keyword to tell Gosu that the subtype overrides an inherited function or method of the same name. If you omit the override keyword, Gosu displays a compiler warning. Additionally, the Gosu editor offers to insert the override modifier if the override keyword seems appropriate.

For example, the following code expands the Vehicle class with abstract members:

package com.mycompany

abstract class Vehicle {

  // An abstract property -- every concrete subtype must implement this!
  abstract property get Plate() : String
  abstract property set Plate(newPlate : String)

  // An abstract function/method -- every concrete subtype must implement this!
  abstract function RegisterWithDMV(registrationURL : String)
}

A concrete subtype of this Vehicle class looks like the following code:

package com.mycompany

class Truck extends com.mycompany.Vehicle {
  var _TruckLength : int as TruckLength

  /* Create a class instance variable that uses the "as ..." syntax to define a property.
   * This variable provides a concrete implementation of the abstract property "Plate".
   */
  var _licenseplate : String as Plate

  /* Implement the function RegisterWithDMV, which is abstract in the supertype, which
   * does not define how to implement the method, but does specify the method signature 
   * that you must implement to support instantiation with "new".
   */
  override function RegisterWithDMV(registrationURL : String ) {
    // Here do whatever needs to be done
    print("Simulation of registering " + _licenseplate + " to " + registrationURL)
  }
}

You can now construct an instance of the concrete subtype Truck, even though you cannot directly construct an instance of the supertype Vehicle because that type is abstract.

Create the classes, and then try the following lines in Gosu Scratchpad to test these classes.

var t = new com.mycompany.Truck()
t.Plate = "ABCDEFG"
print("License plate = " + t.Plate)
t.RegisterWithDMV( "http://dmv.ca.gov/register" )

This code prints the following lines:

License plate = ABCDEFG
Simulation of registering ABCDEFG to http://dmv.ca.gov/register