This article is a compilation of the results of my research into what values are actually output by writing class inheritance in different languages in a similar way. Sometimes I worked hard from Hello World, thinking that there was such a grammar even in a known language.
Who would benefit from it being difficult to put together? However, I will leave it for those who are interested in the same thing. No, there may be new discoveries, so please read it for the time being. It may have been a surprisingly interesting result.
--Static typing
--Dynamic typing
--Optional static typing
A child class inherits a parent class. Its parent and child classes have instance variables with the same name. (Not a class variable) The parent class has a method that you can use to output instance variables to the console.
At run time, the child class instance calls the inherited parent method. Now, the story is ** Which instance variable, parent or child, will be output ** …….
If you write it in JS (ES6 or later) code that many people can probably read, it is such a code.
class SuperClass {
constructor() {
//* In JS, instance variables are defined at runtime, so write them in the constructor.
this.instanceVariable = "SuperClass" //Different values with the same name
}
superClassMethod() {
console.log(this.instanceVariable)
}
}
class SubClass extends SuperClass {
constructor() {
super()
this.instanceVariable = "SubClass" //Different values with the same name
}
}
const sub = new SubClass() //Intensify child class
sub.superClassMethod() //Call the inherited parent class method
Imagine what values are output in the language you normally use. It's an occasional writing style (good or bad), so you may know what you're good at. But if you know how it works in other languages, it may be useful someday when you enter another company or a different project, or when you are interested in getting started in another language.
This time, I'm looking at not only instance variables but also what happens when you do return" SuperClass "
with a method (a method of an instance that is not a class method).
In this case, the parent class and the child class have a method with the same name, and the method of the parent class calls it ....
You can find out what kind of code you wrote and looked up.
class Hoge {}
Since the detailed folding element is placed like this, you can read the code inside by clicking it to open it. It's a pretty WET code that uses copy and paste in principle to make it easier to see what you're doing, but don't throw the chords as it's intentional.
As you know, different programming languages have different grammars and different evaluation methods. I think the points that will change the results this time are as follows.
--Does the access modifier exist? Also, what kind of things are there --Can instance variables with the same name be defined in the parent class and child class in the first place? --Are there instance variable overrides and method overrides? ――How each language handles inheritance itself
Java
Java, the champion of enterprise systems.
Java has access modifiers such as private
and protected
.
private
can only be seen from the current class. protected
can be accessed by the current class and its child classes.
There are no instance variable overrides in Java. So let's see what happens when we override it with a method.
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variables are protected | "SuperClass" |
Private methods instead of instance variables | "SuperClass" |
Protected method (override) instead of instance variable | "SubClass" |
Overrides literally "override".
This time it didn't matter, but Java can access the instance variables of the parent class with methods on the child class side like super.instanceVariable
. It's a trick that you can do because you don't override it.
public class JavaSample {
public static void main(String[] args) {
System.out.println("---- SubClass ----");
SubClass sub = new SubClass();
sub.superClassMethod();
System.out.println("---- SubClassProtected ----");
SubClassProtected subp = new SubClassProtected();
subp.superClassMethod();
System.out.println("---- SubClassGetter ----");
SubClassGetter subg = new SubClassGetter();
subg.superClassMethod();
System.out.println("---- SubClassGetterProtected ----");
SubClassGetterProtected subgp = new SubClassGetterProtected();
subgp.superClassMethod();
}
}
class SuperClass {
//Private instance variables cannot be referenced by subclasses
private String instanceVariable = "SuperClass";
public void superClassMethod() {
System.out.println(instanceVariable);
}
}
class SubClass extends SuperClass {
private String instanceVariable = "SubClass";
}
// -------------------------------------------
class SuperClassProtected {
protected String instanceVariable = "SuperClass";
public void superClassMethod() {
System.out.println(instanceVariable);
}
}
class SubClassProtected extends SuperClassProtected {
protected String instanceVariable = "SubClass";
// public void subClassMethod() {
// System.out.println(instanceVariable);If you write
// System.out.println(this.instanceVariable);Same as."SubClass"coming out.
//With super,"SuperClass"Can also be displayed
// System.out.println(super.instanceVariable);
// }
}
// -------------------------------------------
class SuperClassGetter {
private String instanceVariable() {
return "SuperClass";
}
public void superClassMethod() {
System.out.println(instanceVariable());
}
}
class SubClassGetter extends SuperClassGetter {
private String instanceVariable() {
return "SubClass";
}
}
// -------------------------------------------
class SuperClassGetterProtected {
protected String instanceVariable() {
return "SuperClass";
}
public void superClassMethod() {
System.out.println(instanceVariable());
}
}
class SubClassGetterProtected extends SuperClassGetterProtected {
protected String instanceVariable() {
return "SubClass";
}
}
C#
After Java, after all C #. It has a grammar that is quite similar to Java for historical reasons. The result is also similar to Java and C ++ described below, but there are some that Java does not have. By the way, C # has properties, so I wrote them as properties instead of methods.
There are virtual
and ʻoverridein C #.
virtual is a qualifier that tells you that this method can be overridden, and ʻoverride
is a qualifier that tells you that the method is overriding here.
That's fine, but C # also has a weird qualifier called new
. This new is different from the new of new Human ()
at the time of instantiation. By adding new instead of override, the method of the parent class can be evaluated in the context of the parent class even if it is called from the child class. The reason is that we are not overriding the methods of the parent class, we are just hiding them. It's complicated.
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variables are protected | "SuperClass" |
Property is private | "SuperClass" |
Property protected(override) | "SubClass" |
Property protected(new) | "SuperClass" |
using System;
public class CSharpSample
{
public static void Main(string[] args)
{
Console.WriteLine("---- SubClass ----");
var sub = new SubClass();
sub.SuperClassMethod();
Console.WriteLine("---- SubClassProtected ----");
var subp = new SubClassProtected();
subp.SuperClassMethod();
Console.WriteLine("---- SubClassGetter ----");
var subg = new SubClassGetter();
subg.SuperClassMethod();
Console.WriteLine("---- SubClassGetterProtectedOverride ----");
var subgpo = new SubClassGetterProtectedOverride();
subgpo.SuperClassMethod();
Console.WriteLine("---- SubClassGetterProtectedNew ----");
var subgpn = new SubClassGetterProtectedNew();
subgpn.SuperClassMethod();
}
}
class SuperClass
{
private string instanceVariable = "SuperClass";
public void SuperClassMethod()
{
Console.WriteLine(instanceVariable);
}
}
class SubClass : SuperClass
{
// warning CS0414: The field 'SubClass.instanceVariable' is assigned but its value is never used
private string instanceVariable = "SubClass";
}
// ----------------------------
class SuperClassProtected
{
protected string instanceVariable = "SuperClass";
public void SuperClassMethod()
{
Console.WriteLine(instanceVariable);
}
}
class SubClassProtected : SuperClassProtected
{
//new is not an override, it explicitly states that it hides the instance variable of the inheritance source
new protected string instanceVariable = "SubClass";
}
// ----------------------------
class SuperClassGetter
{
private string instanceVariable
{
get {
return "SuperClass";
}
}
public void SuperClassMethod()
{
Console.WriteLine(instanceVariable);
}
}
class SubClassGetter : SuperClassGetter
{
private string instanceVariable {
get {
return "SubClass";
}
}
}
// ----------------------------
class SuperClassGetterProtected
{
protected virtual string instanceVariable
{
get {
return "SuperClass";
}
}
public void SuperClassMethod()
{
Console.WriteLine(instanceVariable);
}
}
class SubClassGetterProtectedOverride : SuperClassGetterProtected
{
protected override string instanceVariable {
get {
return "SubClass";
}
}
}
class SubClassGetterProtectedNew : SuperClassGetterProtected
{
protected new string instanceVariable {
get {
return "SubClass";
}
}
}
C++
It seems that C ++ is often used in embedded sites, but I don't know anything. C ++ Nanimowa Karanai …….
Along with Java, it is the original language of C #, so its behavior is very similar to C #.
If you use a method instead of an instance variable and do not override it, it behaves the same as new
in C #.
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variables are protected | "SuperClass" |
Private methods instead of instance variables | "SuperClass" |
Protected method (override) instead of instance variable | "SubClass" |
Protected method instead of instance variable (do not override) | "SuperClass" |
#include <iostream>
class SuperClass {
//Private by default (inaccessible from outside the class)
std::string instanceVariable = "SuperClass";
public:
void superClassMethod() {
std::cout << instanceVariable << std::endl;
}
};
class SubClass : public SuperClass {
std::string instanceVariable = "SubClass";
};
// -------------------------------
class SuperClassProtected {
protected:
std::string instanceVariable = "SuperClass";
public:
void superClassMethod() {
std::cout << instanceVariable << std::endl;
}
};
class SubClassProtected : public SuperClassProtected {
protected:
std::string instanceVariable = "SubClass";
};
// -------------------------------
class SuperClassGetter {
std::string instanceVariable() {
return "SuperClass";
}
public:
void superClassMethod() {
std::cout << instanceVariable() << std::endl;
}
};
class SubClassGetter : public SuperClassGetter {
std::string instanceVariable() {
return "SubClass";
}
};
// -------------------------------
class SuperClassProtectedGetter {
protected:
std::string instanceVariable() {
return "SuperClass";
}
public:
void superClassMethod() {
std::cout << instanceVariable() << std::endl;
}
};
class SubClassProtectedGetter : public SuperClassProtectedGetter {
protected:
std::string instanceVariable() {
return "SubClass";
}
};
// -------------------------------
class SuperClassProtectedGetterOverride {
protected:
virtual std::string instanceVariable() {
return "SuperClass";
}
public:
void superClassMethod() {
std::cout << instanceVariable() << std::endl;
}
};
class SubClassProtectedGetterOverride : public SuperClassProtectedGetterOverride {
protected:
std::string instanceVariable() override {
return "SubClass";
}
};
int main()
{
std::cout << "---- SubClass ----" << std::endl;
SubClass sub;
sub.superClassMethod();
std::cout << "---- SubClassProtected ----" << std::endl;
SubClassProtected subp;
subp.superClassMethod();
std::cout << "---- SubClassGetter ----" << std::endl;
SubClassGetter subg;
subg.superClassMethod();
std::cout << "---- SubClassProtectedGetter ----" << std::endl;
SubClassProtectedGetter subpg;
subpg.superClassMethod();
std::cout << "---- SubClassProtectedGetterOverride ----" << std::endl;
SubClassProtectedGetterOverride subpgo;
subpgo.superClassMethod();
return 0;
}
Scala
AltJava that incorporates a functional style. The big difference from Java and C # is that you can ** override instance variables **. New features are here!
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variable protected (override) | "SubClass" |
object ScalaSample {
def main(args: Array[String]): Unit = {
println("---- SubClass ----")
val sub = new SubClass
sub.superClassMethod()
println("---- SubClassProtected ----")
val subp = new SubClassProtected
subp.superClassMethod()
}
}
class SuperClass {
private val instanceVariable = "SuperClass";
def superClassMethod(): Unit = {
println(instanceVariable);
}
}
class SubClass extends SuperClass {
private val instanceVariable = "SubClass";
}
// ----------------------------
class SuperClassProtected {
protected val instanceVariable = "SuperClass";
def superClassMethod(): Unit = {
println(instanceVariable);
}
}
class SubClassProtected extends SuperClassProtected {
override protected val instanceVariable = "SubClass";
}
Kotlin
Alt Java was heavily influenced by Scala. It is often used in the development of Android applications.
Same as Scala, except that you must add open to the instance variable you plan to override.
So ʻopen is like
virtual` in C ++ or C #.
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variable protected (override) | "SubClass" |
fun main(args: Array<String>) {
println("---- SubClass ----");
val sub = SubClass();
sub.superClassMethod();
println("---- SubClassOverride ----");
val subo = SubClassOverride();
subo.superClassMethod();
}
open class SuperClass {
private val instanceVariable = "SuperClass";
fun superClassMethod() {
println(instanceVariable);
}
}
class SubClass : SuperClass() {
private val instanceVariable = "SubClass";
}
// -----------------------------------
open class SuperClassOverride {
open val instanceVariable = "SuperClass";
fun superClassMethod() {
println(instanceVariable);
}
}
class SubClassOverride : SuperClassOverride() {
override val instanceVariable = "SubClass";
}
Swift
Android is not the only app. I don't want you to forget iOS.
It seems that the behavior of Swift's private
changes depending on the version, but this time I verified it with Swift 5, so like Java, it is valid only in the class and is not inherited.
Swift's let
is a variable declaration that prohibits reassignment. In JS, it is const
.
And Swift's var
is a normal variable declaration that can be reassigned. It is let
in JS. It's complicated.
In Swift, you can't define an instance variable (called a property in Swift) that is the same as the inheritance source. You can override it by using Computed Property (like a property in C #) instead.
Without an access modifier like private
, the scope is ʻinternal. ʻInternal
is like public
in Java (miscellaneous).
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variable is internal | Undefinable |
Computed Property is private | "SuperClass" |
Computed Property is internal(override) | "SubClass" |
class SuperClass {
private let instanceVariable = "SuperClass";
func SuperClassMethod() {
print(instanceVariable);
}
}
class SubClass: SuperClass {
private let instanceVariable = "SubClass";
}
// --------------------------------
class SuperClassInternal {
let instanceVariable = "Error";
func SuperClassMethod() {
print(instanceVariable);
}
}
class SubClassInternal: SuperClassInternal {
// error: cannot override with a stored property 'instanceVariable'
// let instanceVariable = "SubClass";
}
// --------------------------------
//Make it a Computed Property and grow a getter. In this case, it is treated as a function, so you can override it.
class SuperClassGetter {
//If it is let, error: 'let' declarations cannot be computed properties
private var instanceVariable: String { get { return "SuperClass" } }
func SuperClassMethod() {
print(instanceVariable);
}
}
class SubClassGetter: SuperClassGetter {
private var instanceVariable: String { get { return "SubClass" } };
}
// --------------------------------
//Make it a Computed Property and grow a getter. In this case, it is treated as a function, so you can override it.
class SuperClassInternalGetter {
//If it is let, error: 'let' declarations cannot be computed properties
var instanceVariable: String { get { return "SuperClass" } }
func SuperClassMethod() {
print(instanceVariable);
}
}
class SubClassInternalGetter: SuperClassInternalGetter {
override var instanceVariable: String { get { return "SubClass" } };
}
print("---- SubClass ----");
let sub = SubClass();
sub.SuperClassMethod();
print("---- SubClassInternal ----");
let subi = SubClassInternal();
subi.SuperClassMethod();
print("---- SubClassGetter ----");
let subg = SubClassGetter();
subg.SuperClassMethod();
print("---- SubClassInternalGetter ----");
let subig = SubClassInternalGetter();
subig.SuperClassMethod();
Python
From here on, a dynamically typed language! Python has made its popularity solid, such as continuing to take first place in Qiita's tag posting ranking.
The characteristic of Python class is that the instance itself comes to the first argument of the method, so when declaring it, write self
as the first argument. It doesn't have to be self
, but everyone writes self
.
After that, like a dynamically typed language, instance variables are dynamically created, so define the instance variables in the constructor instead of directly under the class declaration. This is the same for Ruby and JavaScript.
Python has no member access restrictions. There is no qualifier private
.
It is a culture that puts ** 1 ** underscore at the beginning of the function name to indicate that you do not want to access it.
But in Python, there is a feature in case there is a name conflict with a child class. Adding ** 2 ** underscores changes the internal member name (name mangling), making it easy to make the original variable name inaccessible. This feature allows you to evaluate the result at run time in the context of the original parent class, even if the child class has members with the same name. pep8-ja --naming convention --method name and instance variable Let's see the result.
conditions | result |
---|---|
Instance variables | "SubClass" |
Method instead of instance variable | "SubClass" |
Instance variable (with 2 Ansco) | "SuperClass" |
Method instead of instance variable (with 2 Ansco) | "SuperClass" |
class SuperClass:
def __init__(self):
self.instance_variable = "SuperClass"
def super_class_method(self):
print(self.instance_variable)
class SubClass(SuperClass):
def __init__(self):
super().__init__()
self.instance_variable = "SubClass"
# ------------------------------
class SuperClassNameMangling:
def __init__(self):
self.__instance_variable = "SuperClass"
def super_class_method(self):
print(self.__instance_variable)
class SubClassNameMangling(SuperClassNameMangling):
def __init__(self):
super().__init__()
self.__instance_variable = "SubClass"
# ------------------------------
class SuperClassGetter:
def instance_variable(self):
return "SuperClass"
def super_class_method(self):
print(self.instance_variable())
class SubClassGetter(SuperClassGetter):
def instance_variable(self):
return "SubClass"
# ------------------------------
class SuperClassNameManglingGetter:
def __instance_variable(self):
return "SuperClass"
def super_class_method(self):
print(self.__instance_variable())
class SubClassNameManglingGetter(SuperClassNameManglingGetter):
def __instance_variable(self):
return "SubClass"
print('---- SubClass ----')
sub = SubClass()
sub.super_class_method()
print('---- SubClassNameMangling ----')
subp = SubClassNameMangling()
subp.super_class_method()
print('---- SubClassGetter ----')
subg = SubClassGetter()
subg.super_class_method()
print('---- SubClassNameManglingGetter ----')
subpg = SubClassNameManglingGetter()
subpg.super_class_method()
Ruby
"What about an object-oriented dynamically typed language?" Many programmers who took the associative quiz think of this language first.
Ruby has a private
that can be used for methods, but it behaves differently than the private
in languages like Java. I will not write in detail because I have to explain the receiver etc., but for the time being, I can say that even if there is private
, the method can be seen in the inheritance destination. So in Java, protected
may be closer.
[Ruby] The essence of private methods and the benefits of understanding them
By the way, in Ruby, the namespaces of variables and methods are separate, so you can call methods even if you write them without parentheses.
The method then returns the result of the last evaluated expression without writing a return.
@Variable name
is an instance variable. In Ruby, you can tell the type (scope) of a variable by the first character of the variable name.
conditions | result |
---|---|
Instance variables | "SubClass" |
Method instead of instance variable | "SubClass" |
Private methods instead of instance variables | "SubClass" |
class SuperClass
def initialize()
@instance_variable = "SuperClass"
end
def super_class_method
p @instance_variable
end
end
class SubClass < SuperClass
def initialize()
super()
@instance_variable = "SubClass"
end
end
# --------------------------------
class SuperClassGetter
def instance_variable()
"SuperClass"
end
def super_class_method
p instance_variable
end
end
class SubClassGetter < SuperClassGetter
def instance_variable()
"SubClass"
end
end
# --------------------------------
class SuperClassGetterPrivate
def super_class_method
p instance_variable
end
private
def instance_variable()
"SuperClass"
end
end
class SubClassGetterPrivate < SuperClassGetterPrivate
private
def instance_variable()
"SubClass"
end
end
p '---- SubClass ----'
subc = SubClass.new
subc.super_class_method
p '---- SubClassGetter ----'
subg = SubClassGetter.new
subg.super_class_method
p '---- SubClassGetterPrivate ----'
subgp = SubClassGetterPrivate.new
subgp.super_class_method
PHP
PHP has private
, protected
, and public
like Java.
It's basically not in Python, Ruby, or JavaScript! Jealous!
But unlike Java, protected
instance variables go to read subclasses.
That's a move that is in line with other dynamically typed languages.
conditions | result |
---|---|
Instance variable is private | "SuperClass" |
Instance variables are protected | "SubClass" |
Private methods instead of instance variables | "SuperClass" |
Protected methods instead of instance variables | "SubClass" |
<?php
function println($message)
{
echo $message.PHP_EOL;
}
// ----------------------------------------
class SuperClass
{
private $instanceVariable = "SuperClass";
public function superClassMethod()
{
println($this->instanceVariable);
}
}
class SubClass extends SuperClass
{
private $instanceVariable = "SubClass";
}
// ----------------------------------------
class SuperClassProtected
{
protected $instanceVariable = "SuperClass";
public function superClassMethod()
{
println($this->instanceVariable);
}
}
class SubClassProtected extends SuperClassProtected
{
protected $instanceVariable = "SubClass";
}
// ----------------------------------------
class SuperClassGetter
{
private function instanceVariable()
{
return "SuperClass";
}
public function superClassMethod()
{
println($this->instanceVariable());
}
}
class SubClassGetter extends SuperClassGetter
{
private function instanceVariable()
{
return "SubClass";
}
}
// ----------------------------------------
class SuperClassGetterProtected
{
protected function instanceVariable()
{
return "SuperClass";
}
public function superClassMethod()
{
println($this->instanceVariable());
}
}
class SubClassGetterProtected extends SuperClassGetterProtected
{
protected function instanceVariable()
{
return "SubClass";
}
}
// ----------------------------------------
println("---- SubClass ----");
$sub = new SubClass();
$sub->superClassMethod();
println("---- SubClassProtected ----");
$subp = new SubClassProtected();
$subp->superClassMethod();
println("---- SubClassGetter ----");
$subg = new SubClassGetter();
$subg->superClassMethod();
println("---- SubClassGetterProtected ----");
$subgp = new SubClassGetterProtected();
$subgp->superClassMethod();
JavaScript
The front-end champion. A prototype-based object-oriented language, a language inspired by the programming language Self. Since ES6 and later JavaScript also incorporates class-based writing, it can be inherited by ʻextends`.
conditions | result |
---|---|
Instance variables | "SubClass" |
Instance variables in the old way | "SubClass" |
An instance variable whose calling method is an arrow function | "SubClass" |
Arrow function instead of instance variable | "SubClass" |
class SuperClass {
constructor() {
this.instanceVariable = "SuperClass"
}
superClassMethod() {
console.log(this.instanceVariable)
}
}
class SubClass extends SuperClass {
constructor() {
super()
this.instanceVariable = "SubClass"
}
}
// ------------------------
function LegacySuperClass() {
this.instanceVariable = "SuperClass";
};
LegacySuperClass.prototype.superClassMethod = function() {
console.log(this.instanceVariable)
};
function LegacySubClass() {
this.instanceVariable = "SubClass";
};
LegacySubClass.prototype = new LegacySuperClass();
// ------------------------
class SuperClassArrow {
constructor() {
this.instanceVariable = "SuperClass"
}
superClassMethod = () => {
console.log(this.instanceVariable)
}
}
class SubClassArrow extends SuperClassArrow {
constructor() {
super()
this.instanceVariable = "SubClass"
}
}
// ------------------------
class SuperClassGetterArrow {
instanceVariable = () => {
return "SuperClass"
}
superClassMethod = () => {
console.log(this.instanceVariable())
}
}
class SubClassGetterArrow extends SuperClassGetterArrow {
instanceVariable = () => {
return "SubClass"
}
}
// ------------------------
console.log('---- SubClass ----')
const sub = new SubClass()
sub.superClassMethod()
console.log('---- LegacySubClass ----')
var lsub = new LegacySubClass()
lsub.superClassMethod()
console.log('---- SubClassArrow ----')
const suba = new SubClassArrow()
suba.superClassMethod()
console.log('---- SubClassGetterArrow ----')
const subga = new SubClassGetterArrow()
subga.superClassMethod()
TypeScript
It's cool JavaScript that can be statically typed. There are union types, which are similar to the types found in Haskell, which has an advanced type system, and there are conditional types, mapped types, and other expressive types.
In TypeScript, defining a member with the same name as private
in a parent class and a child class will result in a compile error. If it is protected
, there is no problem. It's the exact opposite of Swift.
conditions | result |
---|---|
Instance variable is private | Undefinable |
Instance variables are protected | "SubClass" |
Private methods instead of instance variables | Undefinable |
The instance variable is protected and the calling method is an arrow function | "SubClass" |
Protected arrow function instead of instance variable | "SubClass" |
class SuperClass {
private readonly instanceVariable: string
constructor() {
this.instanceVariable = "Error"
}
public superClassMethod() {
console.log(this.instanceVariable)
}
}
class SubClass extends SuperClass {
//When I try to define it with instanceVariable
// TS2415: Class 'SubClass' incorrectly extends base class 'SuperClass'.
// private readonly instanceVariable: string
// constructor() {
// super()
// this.instanceVariable = "SubClass"
// }
}
// ------------------------
class SuperClassGetter {
private instanceVariable() {
return "Error"
}
public superClassMethod() {
console.log(this.instanceVariable())
}
}
class SubClassGetter extends SuperClassGetter {
//When I try to define it with instanceVariable
// TS2415: Class 'SubClassGetter' incorrectly extends base class 'SuperClassGetter'.
// Types have separate declarations of a private property 'instanceVariable'.
// private instanceVariable() {
// return "SubClass"
// }
}
// ------------------------
class SuperClassProtected {
protected readonly instanceVariable: string
constructor() {
this.instanceVariable = "SuperClass"
}
public superClassMethod() {
console.log(this.instanceVariable)
}
}
class SubClassProtected extends SuperClassProtected {
protected readonly instanceVariable: string
constructor() {
super()
this.instanceVariable = "SubClass"
}
}
// ------------------------
class SuperClassProtectedGetterArrow {
protected instanceVariable = () => {
return "SuperClass"
}
public superClassMethod = () => {
console.log(this.instanceVariable())
}
}
class SubClassProtectedGetterArrow extends SuperClassProtectedGetterArrow {
protected instanceVariable = () => {
return "SubClass"
}
}
// ------------------------
//Arrow function version
class SuperClassProtectedArrow {
protected readonly instanceVariable: string
constructor() {
this.instanceVariable = "SuperClass"
}
public superClassMethod = () => {
console.log(this.instanceVariable)
}
}
class SubClassProtectedArrow extends SuperClassProtectedArrow {
protected readonly instanceVariable: string
constructor() {
super()
this.instanceVariable = "SubClass"
}
}
console.log('---- SubClass ----')
const sub = new SubClass()
sub.superClassMethod()
console.log('---- SubClassGetter ----')
const subg = new SubClassGetter()
subg.superClassMethod()
console.log('---- SubClassProtected ----')
const subp = new SubClassProtected()
subp.superClassMethod()
console.log('---- SubClassProtectedArrow ----')
const subpa = new SubClassProtectedArrow()
subpa.superClassMethod()
console.log('---- SubClassProtectedGetterArrow ----')
const subpga = new SubClassProtectedGetterArrow()
subpga.superClassMethod()
Dart
It's an impressive language that suddenly has a presence since Flutter became popular.
You don't write private
or public
in Dart. You can make it private by adding an underscore to the member name, but it is different from private
such as Java because it only makes it invisible from outside the library.
conditions | result |
---|---|
Instance variable (with Ansco) | "SubClass" |
Instance variables | "SubClass" |
Method instead of instance variable | "SubClass" |
void main() {
print("---- SubClassPrivate ----");
final subp = new SubClassPrivate();
subp.superClassMethod();
print("---- SubClass ----");
final sub = new SubClass();
sub.superClassMethod();
print("---- SubClassGetter ----");
final subg = new SubClassGetter();
subg.superClassMethod();
}
class SuperClassPrivate {
//If you give an underscore, it becomes Private, but
//Since private is visible to the same library, it looks normal to subclasses here
final String _instanceVariable = "SuperClass";
void superClassMethod() => print(_instanceVariable);
}
class SubClassPrivate extends SuperClassPrivate {
final String _instanceVariable = "SubClass";
}
// ------------------------------------
class SuperClass {
final String instanceVariable = "SuperClass";
void superClassMethod() => print(instanceVariable);
}
class SubClass extends SuperClass {
final String instanceVariable = "SubClass";
}
// ------------------------------------
class SuperClassGetter {
String instanceVariable() => "SuperClass";
void superClassMethod() => print(instanceVariable());
}
class SubClassGetter extends SuperClassGetter {
String instanceVariable() => "SubClass";
}
It was surprisingly fun because there were things I didn't know even in a language I was used to to some extent. Some of the examples I wrote for the first time this time, so there is a way to write it like this! Or something wrong! Please comment if you have any.
Overall, I got the impression that in a dynamically typed language, even when a superclass method is called, it first tries to be evaluated in the subclass context. On the other hand, in a statically typed language, it was like, "Because it is a method of a superclass, the basics are evaluated by the superclass. However, if you override it, that is not the case."
The following five were personally impressive.
--C # has a non-overriding qualifier called new
--Scala and Kotlin are statically typed languages, but you can override instance variables
--Python underscore The two member names were more than just names, they also had an effect.
--PHP has a private
like Java even though it is a dynamically typed language
--TypeScript prevents duplicate private
members with the same name from causing an error at compile time and causing unexpected behavior.
--Fixed an error in the explanation of the Python naming convention. Thank you @shiracamus.
--It was pointed out that the word private
is not used in Python, so I fixed it. Thank you @Luice.
Recommended Posts