[gjs] Class: introduce abstract classes
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Class: introduce abstract classes
- Date: Mon, 21 Nov 2011 14:57:11 +0000 (UTC)
commit 95947ea7eca0b740a728214584300dd82e394e77
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Sun Nov 20 13:31:46 2011 +0100
Class: introduce abstract classes
By setting Abstract: true in the class parameters, you can now
obtain a class that will throw upon instantiation. The class can
still have an _init (that derived class can call) and otherwise works
like all other classes.
https://bugzilla.gnome.org/show_bug.cgi?id=664437
modules/lang.js | 23 +++++++++++++++--------
test/js/testClass.js | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 8 deletions(-)
---
diff --git a/modules/lang.js b/modules/lang.js
index 695d448..344720e 100644
--- a/modules/lang.js
+++ b/modules/lang.js
@@ -178,22 +178,29 @@ function Class(params) {
if (!params.Name) {
throw new TypeError("Classes require an explicit 'name' parameter.");
}
+ let name = params.Name;
- let newClass = function() {
- if (!this._init)
- return this;
-
- return this._init.apply(this, arguments);
- };
+ let newClass;
+ if (params.Abstract) {
+ newClass = function() {
+ throw new TypeError('Cannot instantiate abstract class ' + name);
+ };
+ } else {
+ newClass = function() {
+ if (!this._init)
+ return this;
+
+ return this._init.apply(this, arguments);
+ };
+ }
let parent = params.Extends;
if (!parent)
parent = _Base;
- let name = params.Name;
let propertyObj = { };
let propertyDescriptors = Object.getOwnPropertyNames(params).forEach(function(name) {
- if (name == 'Name' || name == 'Extends')
+ if (name == 'Name' || name == 'Extends' || name == 'Abstract')
return;
let descriptor = Object.getOwnPropertyDescriptor(params, name);
diff --git a/test/js/testClass.js b/test/js/testClass.js
index c5f5110..06c37d3 100644
--- a/test/js/testClass.js
+++ b/test/js/testClass.js
@@ -68,6 +68,32 @@ const Accessor = new Lang.Class({
}
});
+const AbstractBase = new Lang.Class({
+ Name: 'AbstractBase',
+ Abstract: true,
+
+ _init: function() {
+ this.foo = 42;
+ }
+});
+
+const AbstractImpl = new Lang.Class({
+ Name: 'AbstractImpl',
+ Extends: AbstractBase,
+
+ _init: function() {
+ this.parent();
+ this.bar = 42;
+ }
+});
+
+const AbstractImpl2 = new Lang.Class({
+ Name: 'AbstractImpl2',
+ Extends: AbstractBase,
+
+ // no _init here, we inherit the parent one
+});
+
function testClassFramework() {
let newMagic = new MagicBase('A');
assertEquals('A', newMagic.a);
@@ -126,4 +152,17 @@ function testAccessor() {
assertEquals(42, newAccessor.value);
}
+function testAbstract() {
+ assertRaises(function() {
+ let newAbstract = new AbstractBase();
+ });
+
+ let newAbstract = new AbstractImpl();
+ assertEquals(42, newAbstract.foo);
+ assertEquals(42, newAbstract.bar);
+
+ newAbstract = new AbstractImpl2();
+ assertEquals(42, newAbstract.foo);
+}
+
gjstestRun();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]