Skip to content

MiddleClass vs LowerClass

Devon Palma edited this page Nov 6, 2024 · 1 revision

LowerClass is modeled after MiddleClass's Wiki by Kikito. Many similarities exist but differ in two main functionalities:

  1. Static Support (MiddleClass) vs No Static Support (LowerClass)
  2. Single-Inheritance (MiddleClass) vs Multi-Inheritance (LowerClass)

There are some additional syntatic changes I made, but overall if you've used MiddleClass, LowerClass will come very naturally.

No-Static

MiddleClass's static functionallity was removed. Whilst a cool feature, overall it added more complexity that it was worth. Instead all functions defined in a class are now both static and instance based.

MiddleClass:

local TestClass = class('Test')

TestClass.static.exampleStaticFunc()
  print('This is a static function')
end

TestClass.exampleStaticFunc()

LowerClass:

local TestClass = class('Test')

TestClass.exampleFunc()
  print('This is an example function')
end

TestClass.exampleFunc()

Multi-Inheritance

MiddleClass only supported having a single parent class. This was neat, but I really like having multi-class inheritance.

'super' has been removed from the class dictionary. This was previously a reference to the active class' parent. Instead of using super(), just directly reference the class.

MiddleClass:

local ClassA = class('ClassA')
local ClassB = class('ClassB', ClassA)

ClassB.static.exampleStaticFunc(self)
  print('This is class ' .. self.name .. ', my parent is ' .. self.super.name .. '.')
end

ClassB:exampleStaticFunc()

LowerClass:

local ClassA = class('ClassA')
local ClassB = class('ClassB', ClassA)

ClassB.exampleFunc(self)
  print('This is class ' .. ClassB.name .. ', my parent is ' .. ClassA.name .. '.')
end

ClassB:exampleStaticFunc()

Inheritance / Mixins

Tied closely to the above, LowerClass simplifies both how mixins and inheritance works. Mixins behave exactly the same. With the support of multi-inheritance, the include function now supports adding a parent class by passing it as the variable.

LowerClass:

local testMixin = {
  fly = function(self)
    print('Flapping like a bird')
  end
}

local ClassA = class('ClassA')
local ClassB = class('ClassB')

ClassB:include(ClassA) -- ClassA is now a parent of ClassB. ClassB will now inherit all functions added to ClassA.
ClassA:include(testMixin) -- Added the fly function to ClassA, and by proxy ClassB.

is / isInstanceOf

MiddleClass offers the ability to check if an instance/class is a part of another class, but this utilized the static method. I condensed both obj:isInstanceOf() and class:isSubclassOf() down to class:is() / obj:is().

*Please note the new is() function will be the highest preformance impacting change. This is simply because of looping over every parent. If you keep class heiracrhy simple, it shouldn't really impact preformance.

MiddleClass:

local ClassA = class('ClassA')
local ClassB = class('ClassB', ClassA)

local objA = ClassA:new()
local objB = ClassB:new()

print(objA:isInstanceOf(ClassA)) -- True
print(objA:isInstanceOf(ClassB)) -- False
print(objB:isInstanceOf(ClassA)) -- True
print(objB:isInstanceOf(ClassB)) -- True

print(ClassA:isSubclassOf(ClassB)) -- False
print(ClassB:isSubclassOf(ClassA)) -- True

LowerClass:

local ClassA = class('ClassA')
local ClassB = class('ClassB', ClassA)

local objA = ClassA:new()
local objB = ClassB:new()

print(objA:is(ClassA)) -- True
print(objA:is(ClassB)) -- False
print(objB:is(ClassA)) -- True
print(objB:is(ClassB)) -- True

print(ClassA:is(ClassB)) -- False
print(ClassB:is(ClassA)) -- True

Internal Storage

MiddleClass stored all variables associated with a class inside the class. LowerClass shifts all important internal class data into a localized weak-keyed table. Whilst this won't impact user interaction, its a significant enough change to simply note it.

This includes:

  • Class Heirarchy (parent/children)
  • Class Variables
Clone this wiki locally