-6

Before I go on:
This is an absolutely abstracted question. Don't ask what are you trying to do.

Here's the thing:
Look at this two pieces of code in two different syntax. (syntaxes?)
I use the second one almost exclusively, and comes with the 2nd one an ability that's not possible in the other one.
I don't know about OO in Java/C#.
I want to know where Java/C# stand, on this ability.
My question is about that ability, and:
If that ability is possible in C#/Java? (I know that it's not possible in the first syntax)
Is it totally flawed in terms of OO principles in C#/Java? (cuz I tought maybe there's a reason it's not possible in the first syntax)
Is it an unwanted thing?

While I'm not sure about the terminology, this ability that I'm talking about is returing the super.

the first syntax: (which is es6 stuff)

var log = console.log;

class Gender {
    constructor(type) {
        this.gender = type;
    }
    sayGender() {
        log(this.gender);
        return this;
    }
}
class Person extends Gender {
    constructor(gender, name, age) {
        super(gender);
        this.name = name;
        this.age = age;
    }
    sayName() {
        log(this.name);
        return this;
    }
    sayAge() {
        log(this.age);
        return this;
    }
    saySomething() {
    // only limited access to super methods.
    // access limited to calling super methods/getters/setters and not public properties.
    // (also not possible to return them since they're just imaginary refrences and not values)
    // this === invoked instance
    // super === reference to implicit derived instance (not returnable since not value)
    // no access to super/base instance (instance of Person)
    log("you can't break the chain here, even if u wanted to");
    return this;
}
class Employee extends Person {
    constructor(gender, name, age, jobTitle) {
        super(gender, name, age);
        this.jobTitle = jobTitle;
    }
    sayJob() {
        log(this.jobTitle);
        return this;
    }
}

here's the second syntax

var log = console.log;
function newGender(type) {
    let inst = {};
    inst.gender = type;

    inst.sayGender = function () {
        log(gender); // or this.gender if u want (but context-less calls will no longer be available)
        return this;
    };

    return inst;
}
function newPerson(gender, name, age) {
    let _super_ = newGender(gender);
    let inst = Object.create( _super_ );

    let privateVariable;
    function privateFunction() {} // not possible with the other syntax

    inst.name = name;
    inst.age = age;

    inst.sayName = function () {
        log(name);
        return this;
    };
    inst.sayAge = function () {
        log(age);
        return this;
    };
    inst.saySomething = function () {
    // full access to super/base, derived, and invoked instances. (even returning them since they're values now).
    // differentiation between super/base, derived, and invoked instances in the context of current class.
    // _super_ === base instance
    // inst === derived instance
    // this === invoked instance
    log("you can break the chain here if u want");
    return inst;
    };

    return inst;
}
function newEmployee(gender, name, age, jobTitle) {
    let _super_ = newPerson(gender, name, age);
    let inst = Object.create( _super_ );

    inst.jobTitle = jobTitle;

    inst.sayJob = function () {
        log(jobTitle);
        return this;
    };

    return inst;
}

Diffs:

method chaining:

var t = new Employee("male", "mohammad", 28, "web developer")
t.sayGender()        //  "male"
    .sayName()       //  "mohammad"
    .sayAge()        //  28
    .saySomething()  //  "you can't break the chain here, even if u wanted to"
    .sayJob()        //  "web developer"

var t = newEmployee("male", "mohammad", 28, "web developer")
t.sayGender()        //  "male"
    .sayName()       //  "mohammad"
    .sayAge()        //  28
    .saySomething()  //  "you can break the chain here if u want"
    // I can't chain after this point since I returned the super and sayJob() is not defined on it.
    .sayJob()        //  "web developer"

context-less calls:

var t = new Employee("male", "mohammad", 28, "web developer")
var sayJob = t.sayJob;
sayJob() // TypeError: Cannot read property 'jobTitle' of undefined

var t = newEmployee("male", "mohammad", 28, "web developer")
var sayJob = t.sayJob;
sayJob() // web developer

Edit:

The question is not about Java or C# or JavaScript.

When you call the constructor of a derived class in JavaScript (with new)
there is an implicit super instance available for your derived instance (since all derived class constructors must contain a super() call). But you can only use methods (and getters/setters) of this implicit instance and not properties.
So inside the sayName() method of the Person class I can say super.someMethod() or super["name of a setter"] = "a value"; or super["name of a getter"]; // and u can read it

So I have access to the super instance but my access is limited. Hence why you can't return it, yes I know super is not a value =)))).
Now imagine you get full access to the instance that super points to. right?
What I mean by full access is imagine you get that instance right there as a value, So now you can return it or whatever.

What I'm asking you is If you're a Java/C# developer and you work with hierarchical inheritance a lot and have experience in doing so, tomorrow I will show up at where you work, or email you or something and I will tell you that I have a big news for you:
from this day forward there's gonna be two changes in Java/C# lang:
1 super now points to the base class instance.
2 super is now a value, is an actual instance in the context of your derived class, and you can do whatever you want with it. YOU CAN EVEN RETURN IT IN A METHOD!!!
What do you say? what are your thoughts?

(one scenario would be that now a method can return the super instance, and if somebody is chaining some methods from outside and calls this method the next instance that will be returned will not have the derived instance methods anymore)

Final Edit: The way I would write this question after the discussions in comments (though I'm not sure if this way is better or not since it's longer):

In JavaScript a class, behaves as follow: (and when I say a class I mean the fake classical inheritance that we pretend it to be with the underlaying prototypal system)
It must have a constructor which is called when you instantiate it with a new kewrod (var t = new Person()) and you get an instance (or object) of that class. So when you're defining your class eg:

class Person() { // from this curly

} // to this curly  

You can reference that instance that will get created if someone calls new.
Not a complicated thing so far. Let's keep going. So a class can be derived from another class. and this thing adds to the complexity. why? well let's see:
Now we must go through the behaviour of a derived class.
A derived class shares the same behaviours with a base class except a few:
A derived class has a constructor and inside those curlies you would reference the instance (that will get created after the call to new), and all of that, just like a base class.
But a derived class has some behaviours which it doesn't share with the base class. so let's go through them, here's a derived class definiteion:

class Employee extends Person {
    constructor() {
        super()
    }
}

A derived class while has a constructor just like a base class, it also has an aditional rule that is: its constructor must contain a super() call, what that does is it's going to call the base class constructor. So now inside the curlies of a derived class in adition to the this keyword (which was the to be created instance) we also have a super keyword.
What the super keyword allows you to do is to reference an object just like this except that it's not the object that you would get if you would call new no it's not that object, it's the object that you would get if you would instantiate the base class (new Person()), but it differs from you instantiating that base class manually, how it differes? It differes because if you would've isntantiate that base class manually with a new call you would've get all the public methods, properties, getter and setters of that class. but that's not extactly what's happening with the super keyword.
So with the super keyword although you are actually referencing that instance of the base class and there is an (implicit) instance of that base class avaiable for your derived instance (inside the curlies), you don't get to access the properties (even the public ones) of that instance you only get to use public methods. (while there's no public private in es6 js, but let's pretend it is. like typescript).
So now we see that inside the curlies of a devided class we have access to that instance, though limited to methods, but still access and important to remeber that the super keyword is like an imaginary thing and is not a value.

So everything normal so far nothing special. Here's my dilemma:
Due to JavaScript internal system, I have an ability which gives me an option for when I'm constructing objects, let's see what that ability is and more importantly and finaly my question about that ability:
This ability that I keep mentioning is:
Remeber that I said: super is just like an instance of a base class that you manually instantiated but with limitations? well now I can treat the super as if it was really an instance of the base class that I manually instantiated. so now not only I get to access all of it's members (properties and methods) withouth the limitations of super, but since it's a value now, I get to return it in a derived method as well, and cause a chain break (which I feel like it's sorta like a better not to have and not need etc etc deal).

The following are the two abilities that I can come up with so far:

#1 One aspect is when you chain methods, with the class syntax, I would always have one instance, one object. and after one step in a chain. I could access all methods of that instance, and the fact that some of those methods are owned and some of them are inherited wouldn't matter. but with the value kind super I could put stop breaks in that chain. so what could be the use of it? Well I'm not sure, but what I can think of right now is maybe I could have a cue to differentiate between owned and inherited methods. so now If a method breaks the chain I know that that method is been inherited somewhere up the hiearchy.

#2 One other aspect is context-less calls, but let's ingore it as I'm not sure if there's such thing in Java/C#. (but shortly just to be clear: context-less call means you call the method without a context, or in another words, without providing which object should this keyword points to).

These two abilities are the ones that stump me, as I don't know the reasoning in O-O the way I want to know (like the back of my hand), so while I like these abilities, I'm not sure where they would lead the system. and I don't know how to measure it or how to foresee the future of it, so I thought to ask for the opinion of a Java/C# programmer.

P.S. Both of the updated answers are accepted answers.

user2263572
  • 35
  • 1
  • 9
  • What is the feature of the second that isn't possible in the first? – ControlAltDel Jun 26 '17 at 20:19
  • 7
    "Java/C#" and then JavaScript? Some tags need to be narrowed down. – Salem Jun 26 '17 at 20:20
  • 1
    So you're asking about Java? Or about C#? Or about JavaScript? They're not all identical. – Dawood ibn Kareem Jun 26 '17 at 20:37
  • Removed the Java C# tags, but not sure where is the source of confusion, if you look at the code snippet it's clear that this ability that I'm talking about is present in JavaScript. What I'm saying is imagine you had this in Java or C#. – user2263572 Jun 27 '17 at 00:11
  • @ControlAltDel the ability to treat super as a value and return it. or access it's public properties (I know no pub priv in js but just sayin) and break the class hierarchical access chain and forcing outer access to be explicit WHILE CHAINING (not other times but only when using method chaining technique) – user2263572 Jun 27 '17 at 01:50
  • @ControlAltDel the ability to treat super as a value and return it. or access it's public properties and break the class hierarchical access chain and forcing outer access to be explicit ONLY WHILE CHAINING (not other times but only when using method chaining technique) – user2263572 Jun 27 '17 at 01:56
  • @user2263572 *"not sure where is the source of confusion"* Perhaps the title: "Can you return the super in **Java/C#**?" --- And you've already got multiple answers telling you that `super` is not a value. It can't be returned. It's a syntactical construct allowing a subclass to invoke base class methods/constructors and access base class fields. It's a *qualifier*. – Andreas Jun 27 '17 at 13:33
  • If you're asking if you can return the base class, such that the caller cannot call subclass methods on the returned reference, then yes, just change the declared return type of the method. Java is statically typed, so it won't see methods added by subclass, if type of reference is the base class. Note that if subclass *overrides* a base class method, it will be the subclass version of the method that is called. – Andreas Jun 27 '17 at 13:37
  • @Andreas Thank you, that was very useful. (2nd comment) I think that should be in your answer. (So that ability in 2nd snippet is possible in Java but through that static type mechanism that you described) (I'm not looking for implementation details of Java or C#, I'm looking for the big picture reasoning and philosophy) – user2263572 Jun 27 '17 at 14:23
  • @Andreas "you've already got multiple answers telling you that super is not a value" Well I think that just shows you didn't grasp all the little cues that I put in my code. (Feels like nobody even read the code, it's all in there, although u need a bit of info about how js works to fully get it, but still answers and comments in this post feels like everybody trying to answer as fast as possible and not even think about what the op is looking for) – user2263572 Jun 27 '17 at 14:29
  • @user2263572 Perhaps because you didn't *explain* what you were looking for (in original question). You just threw some code in there and expected us to understand what aspect of the code you where thinking about. Many questions on here will include a lot of irrelevant code, so the most difficult part of answering, is deciphering which part is important. Frustratingly enough, many other questions include too little. Anyway, have a look at [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) – Andreas Jun 27 '17 at 14:34
  • @Andreas No I know it's hard and I thank you for your time and I get that it's not a normal question since I'm wondering around in three different languages and their philosophy which may originates from one source but in reality is not the same thing and there's a lot of subtle and little differences. – user2263572 Jun 27 '17 at 14:43

2 Answers2

2

This answer is for Java, though I believe it's the same for C#.

this and super are both the same object. As an object reference, there is no difference.

So No, there is no need to return super, so that is not valid syntax, but Yes you can return this, which is also a reference to super.


UPDATE

The updated question is about method chaining, and whether it's possible to return the base class from a method, so the next method call in chain cannot use methods from the subclass.

The answer is yes and no.

Yes, you can change the declared method return type to be the base class. Since Java is statically typed, only methods declared in the base class will be available for the next method call.

No, you can't fully restrict method calls to base class methods, because the returned object is still the subclass, even though the compiler doesn't know that, and any methods of the base class that was overridden by the subclass, will still invoke the subclass method, even though the declared type is the base class.

This difference is an aspect of both the class- vs. prototype-inheritance models, and the static vs. dynamic typing of the two languages (Java vs. JavaScript, respectively).

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • 2
    same in C# afaik, though it's called `base` – Salem Jun 26 '17 at 20:21
  • The keyword `super` is not a reference to an object at all. There's one special case where it's used where you might usually use a reference to an object -- accessing superclass members in the context of an instance. But there is a difference between `this` and `super` -- the value of the former can be used as a reference. – Andy Thomas Jun 26 '17 at 20:45
  • But `this` and `super` don't mean the same object in JavaScript. `this` means the instance, `super` means the super instance (base instance or parent object without the properties, only methods). Every derived class must call super class constructor. You call parent instance/class methods with super. – user2263572 Jun 27 '17 at 00:37
  • @user2263572 That's JavaScript. You're asking about Java and C#. Three entirely different languages, so don't except them to have the same features. JavaScript *prototype*-based inheritance is entirely different from Java and C# *class*-based inheritance, e.g. see [prototype based vs. class based inheritance](https://stackoverflow.com/q/816071/5221149). – Andreas Jun 27 '17 at 03:28
  • I know exactly how JavaScript inheritance works. I know nothing but JavaScript. The purpose of the second code snippet in the question is to replicate a classical inheritance mechanism with the prototypal one. – user2263572 Jun 27 '17 at 03:33
0

Java does not allow you to use super as a value. You cannot return it. And you don't need to return it, because you can reference the object with this.

In Java, an instance of class is represented by one object. The superclass is not represented by a separate object.

Classes support inheritance of implementation from a superclass. This allows us to write common code that be used or overridden by subclasses.

Superclasses and interfaces support polymorphism. For example, a reference of a superclass type can be used to call methods from a subclass object. This allows us to exploit the Liskov Substitution Principle to write code once that can handle multiple types. This helps us not repeat ourselves. From the Java Language Specification, section 1.1: 1.1 Organization of the Specification:

Classes support single implementation inheritance, in which the implementation of each class is derived from that of a single superclass ... Variables of a class type can reference an instance of that class or of any subclass of that class, allowing new types to be used with existing methods, polymorphically.

Java does allow you to refer to the superclass with the keyword super -- but only to:

  • Call a superclass constructor with arguments
  • Access members of the superclass, from within the subclass.

Details

From the Java Language Specification, section 8.8.7.1, Explicit constructor invocations

Superclass constructor invocations begin with either the keyword super (possibly prefaced with explicit type arguments) or a Primary expression or an ExpressionName. They are used to invoke a constructor of the direct superclass.

From the Java Language Specification, section 15.11.2, Accessing Superclass Members using super:

The form super.Identifier refers to the field named Identifier of the current object, but with the current object viewed as an instance of the superclass of the current class.

So super is a keyword. But the language does not support using super as a value.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • I kinda get it. so this ability that I was talking about basically means nothing in the world of Java. `super` is the same in js except u can only access methods (and not properties) of the superclass (when I say superclass I mean super instance/class minus the props, again same thing all derived classes must have a super call in their constrcutor). – user2263572 Jun 27 '17 at 00:49
  • @user2263572 - That does sound very similar, with the additional restriction you mention. – Andy Thomas Jun 27 '17 at 00:54
  • "you don't need to return it, because you can reference the object with this", well `this` references the derived instance, and not the base instance, Imagine you could return the super/base instance. so now a method on a derived class could break the class hierarchy. (or imagine if the method would get the entire super instance and return it for some purpose) – user2263572 Jun 27 '17 at 01:44
  • **They're the same instance.** There is only one object. You can can return it as the superclass type, if you want, but `this` is all you need to refer to the instance, regardless of the type you want to return. – Andy Thomas Jun 27 '17 at 13:19
  • Downvoter, care to explain? As far as I know, this answer is correct and addresses the original question. – Andy Thomas Jun 27 '17 at 13:20
  • I should've mentioned I was talking about JavaScript not Java. "They're the same instance." is not true in js. – user2263572 Jun 27 '17 at 14:04
  • I think reaction to the question is too literal, I'm not looking for implementation details of Java or C#, I'm looking for the big picture reasoning and philosophy. That's why I said question is not about any of these languages. (but it's ok if u downvote cuz I understand it's not a normal SO question) – user2263572 Jun 27 '17 at 14:14
  • The big picture is polymorphism. A reference of a superclass type can be used to call methods from a subclass object. This allows us to exploit the Liskov Substitution Principle to write code once that can handle multiple types, and not repeat ourselves. From the JLS: *"Classes support single implementation inheritance, in which the implementation of each class is derived from that of a single superclass ... Variables of a class type can reference an instance of that class or of any subclass of that class, allowing new types to be used with existing methods, polymorphically."* – Andy Thomas Jun 27 '17 at 14:31
  • That's very useful to me (ur last comment) thank you for that. I think it should be in your answer. – user2263572 Jun 27 '17 at 14:35
  • @user2263572 - Good idea; done. – Andy Thomas Jun 27 '17 at 14:48