My junior asked me about Java class inheritance, but I couldn't answer it immediately, so I did a lot of research.
Old @IT Conference Room: About Variable Inheritance
Excerpt because it is difficult to read
When a variable with the same name exists in the superclass, the method of the superclass When executed, the variable with the same name referred to the superclass. How can I refer to the variable with the same name in my class?
Below is a sample source. What I thought would return "I am a child" returned "I am a parent."
Main.java
//Execution class
public class Main{
public static void main(String args[]){
Child c1 = new Child();
c1.print();
}
}
//Super class
class Parent{
private String JIBUN = "parent";
public void print(){
System.out.println("I" + JIBUN + "is.");
}
}
//Child class
class Child extends Parent{
private String JIBUN = "children";
}
He said that he didn't understand even if he read the explanation.
The moment I saw it, I thought that JIBUN is private, so it can't be referenced from other classes, and Parent and Child are different, right? It was that.
But what if it's protected (public)? I came up with the question, so I investigated it properly.
Below is the source used for the test. piza.io
Main.java
//Execution class
public class Main{
public static void main(String args[]){
Child c1 = new Child();
c1.print();
c1.print2();
Parent parent = new Child();
c1.print();
c1.print2();
}
}
//Super class
class Parent{
private String JIBUN1 = "Parent 1";
protected String JIBUN2 = "Parent 2";
protected String JIBUN3 = "Parent 3";
public void print(){
System.out.println("print");
System.out.println("I" + JIBUN1 + "is.");
System.out.println("I" + JIBUN2 + "is.");
System.out.println("I" + JIBUN3 + "is.");
}
// final public void print2(){If you don't want to override it, add final and you will get a compile error.
public void print2(){
System.out.println("print2");
System.out.println("Parents" + JIBUN1 + "is.");
System.out.println("Parents" + JIBUN2 + "is.");
System.out.println("Parents" + JIBUN3 + "is.");
}
}
//Child class
class Child extends Parent{
// @Override //Compile error because it cannot be overridden
private String JIBUN1 = "Child 1";
// @Override //Compile error because it cannot be overridden
protected String JIBUN2 = "Child 2";
Child() {
this.JIBUN3 = "Child 3";
}
@Override //Override annotation clearly states that it is an override
public void print2(){
System.out.println("print2");
System.out.println("Children" + JIBUN1 + "is.");
System.out.println("Children" + JIBUN2 + "is.");
System.out.println("Children" + JIBUN3 + "is.");
}
}
Execution result
print
I am parent 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is child 2.
The child is child 3.
print
I am parent 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is child 2.
The child is child 3.
The results are summarized below.
Actually, I originally learned object-oriented programming in C #, so it was easier to write.
This time, there are method overrides and hiding, so there are print2 (override) and print3 (hiding).
Main.cs
using System;
public class Test {
public static void Main(){
Child c1 = new Child();
c1.print();
c1.print2();
c1.print3();
Parent parent = new Child();
parent.print();
parent.print2();
parent.print3();
}
}
//Super class
public class Parent{
// virtual //Compile error because it cannot be overridden
private string JIBUN1 = "Parent 1";
// virtual //Compile error because it cannot be overridden
protected string JIBUN2 = "Parent 2";
// virtual //Compile error because it cannot be overridden
protected string JIBUN3 = "Parent 3";
public void print(){
Console.WriteLine("print");
Console.WriteLine("I" + JIBUN1 + "is.");
Console.WriteLine("I" + JIBUN2 + "is.");
Console.WriteLine("I" + JIBUN3 + "is.");
}
virtual public void print2(){
Console.WriteLine("print2");
Console.WriteLine("Parents" + JIBUN1 + "is.");
Console.WriteLine("Parents" + JIBUN2 + "is.");
Console.WriteLine("Parents" + JIBUN3 + "is.");
}
public void print3(){
Console.WriteLine("print3");
Console.WriteLine("Parents" + JIBUN1 + "is.");
Console.WriteLine("Parents" + JIBUN2 + "is.");
Console.WriteLine("Parents" + JIBUN3 + "is.");
}
}
//Child class
public class Child : Parent{
// override //Compile error because it cannot be overridden
private string JIBUN1 = "Child 1";
// override //Compile error because it cannot be overridden
protected string JIBUN2 = "Child 2";
public Child() {
this.JIBUN3 = "Child 3";
}
override public void print2(){
Console.WriteLine("print2");
Console.WriteLine("Children" + JIBUN1 + "is.");
Console.WriteLine("Children" + JIBUN2 + "is.");
Console.WriteLine("Children" + JIBUN3 + "is.");
}
// override public void print3(){Compile error because print3 does not have virtual
public void print3(){ //Just an overwrite definition
Console.WriteLine("print3");
Console.WriteLine("Children" + JIBUN1 + "is.");
Console.WriteLine("Children" + JIBUN2 + "is.");
Console.WriteLine("Children" + JIBUN3 + "is.");
}
}
Output result
print
I am parent 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is child 2.
The child is child 3.
print3
The child is child 1.
The child is child 2.
The child is child 3.
print
I am parent 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is child 2.
The child is child 3.
print3
The parent is parent 1.
The parent is parent 2.
Parent is child 3.
Compile error (warning)
Compilation succeeded - 2 warning(s)
Main.cs(49,22): warning CS0108: `Child.JIBUN2' hides inherited member `Parent.JIBUN2'. Use the new keyword if hiding was intended
Main.cs(21,22): (Location of the symbol related to previous warning)
Main.cs(60,17): warning CS0108: `Child.print3()' hides inherited member `Parent.print3()'. Use the new keyword if hiding was intended
Main.cs(36,17): (Location of the symbol related to previous warning)
The results are summarized below.
Well, that feeling was cultivated in C #, so it's an individual impression.
I haven't coded C ++ seriously, so I'll try to google it.
There are also print2 and print3 here.
Main.cpp
#include <iostream>
using namespace std;
//Super class
class Parent{
private:
// virtual //Compile error because it cannot be overridden
string JIBUN1 = "Parent 1";
protected:
// virtual //Compile error because it cannot be overridden
string JIBUN2 = "Parent 2";
// virtual //Compile error because it cannot be overridden
string JIBUN3 = "Parent 3";
public:
void print() {
cout << "print" << endl;
cout << "I" + JIBUN1 + "is." << endl;
cout << "I" + JIBUN2 + "is." << endl;
cout << "I" + JIBUN3 + "is." << endl;
};
virtual void print2() {
cout << "print2" << endl;
cout << "Parents" + JIBUN1 + "is." << endl;
cout << "Parents" + JIBUN2 + "is." << endl;
cout << "Parents" + JIBUN3 + "is." << endl;
}
void print3() {
cout << "print3" << endl;
cout << "Parents" + JIBUN1 + "is." << endl;
cout << "Parents" + JIBUN2 + "is." << endl;
cout << "Parents" + JIBUN3 + "is." << endl;
}
};
//Child class
class Child : public Parent{
private:
string JIBUN1 // override //Compile error because it cannot be overridden
= "Child 1";
protected:
string JIBUN2 // override //Compile error because it cannot be overridden
= "Child 2";
public:
Child() {
this->JIBUN3 = "Child 3";
};
void print2() override {
cout << "print2" << endl;
cout << "Children" + JIBUN1 + "is." << endl;
cout << "Children" + JIBUN2 + "is." << endl;
cout << "Children" + JIBUN3 + "is." << endl;
}
// void print3() override {Compile error because print3 does not have virtual
void print3() { //Just an overwrite definition
cout << "print3" << endl;
cout << "Children" + JIBUN1 + "is." << endl;
cout << "Children" + JIBUN2 + "is." << endl;
cout << "Children" + JIBUN3 + "is." << endl;
}
};
int main(void){
Child *c1 = new Child();
c1->print();
c1->print2();
c1->print3();
Parent *parent = new Child();
parent->print();
parent->print2();
parent->print3();
}
Execution result
print
I am parent 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is child 2.
The child is child 3.
print3
The child is child 1.
The child is child 2.
The child is child 3.
print
I am parent 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is child 2.
The child is child 3.
print3
The parent is parent 1.
The parent is parent 2.
Parent is child 3.
There were no particular compilation errors (warnings).
The results are summarized below.
I also investigated the LL language at this time. The class is python that looks like a retrofit.
Since the assumptions are different, the source has quite different meanings. sorry. (JIBUN1 and JIBUN2 are class fields)
There are print2 and print3 here as well, but they are the same because they cannot be written separately.
main.py
# coding: utf-8
# Your code here!
def main():
c1 = Child()
c1.print()
c1.print2()
c1.print3()
parent = Parent()
parent.print()
parent.print2()
parent.print3()
#Super class
class Parent(object):
JIBUN1 = "Parent 1"
JIBUN2 = "Parent 2"
def __init__(self):
self.JIBUN3 = "Parent 3"
def print(self):
print("print")
print("I" + self.JIBUN1 + "is.")
print("I" + self.JIBUN2 + "is.")
print("I" + self.JIBUN3 + "is.")
def print2(self):
print("print2")
print("Parents" + self.JIBUN1 + "is.")
print("Parents" + self.JIBUN2 + "is.")
print("Parents" + self.JIBUN3 + "is.")
def print3(self):
print("print3")
print("Parents" + self.JIBUN1 + "is.")
print("Parents" + self.JIBUN2 + "is.")
print("Parents" + self.JIBUN3 + "is.")
#Child class
class Child(Parent):
JIBUN1 = "Child 1"
def __init__(self):
super(Parent, self).__init__()
self.JIBUN3 = "Child 3"
def print2(self):
print("print2")
print("Children" + self.JIBUN1 + "is.")
print("Children" + self.JIBUN2 + "is.")
print("Children" + self.JIBUN3 + "is.")
def print3(self):
print("print3")
print("Children" + self.JIBUN1 + "is.")
print("Children" + self.JIBUN2 + "is.")
print("Children" + self.JIBUN3 + "is.")
if __name__ == '__main__':
main()
Execution result
print
I am a child 1.
I am parent 2.
I am 3 kids
print2
The child is child 1.
The child is parent 2.
The child is child 3.
print3
The child is child 1.
The child is parent 2.
The child is child 3.
print
I am parent 1.
I am parent 2.
I'm parent 3
print2
The parent is parent 1.
The parent is parent 2.
The parent is parent 3.
print3
The parent is parent 1.
The parent is parent 2.
The parent is parent 3.
The results are summarized below.
Well, it feels easy to understand.
Even in the LL language, ruby seems to have designed the class from the beginning, so for reference. ruby I just scratched it a little.
This is also a source with a quite different meaning.
Main.rb
# coding: utf-8
# Your code here!
def main()
c1 = Child.new
c1.print
c1.print2
Child.print3
parent = Parent.new
parent.print
parent.print2
Parent.print3
end
#Super class
class Parent
@JIBUN1 = "Parent 1"
@@JIBUN2 = "Parent 2"
def initialize
@JIBUN3 = "Parent 3"
end
def print
p "print"
p "I" + (@JIBUN1 || 'undefined') + "is."
p "I" + (@@JIBUN2 || 'undefined') + "is."
p "I" + @JIBUN3 + "is."
end
def print2
p "print2"
p "Parents" + (@JIBUN1 || 'undefined') + "is."
p "Parents" + (@@JIBUN2 || 'undefined') + "is."
p "Parents" + @JIBUN3 + "is."
end
def self.print3
p "print3"
p "Parents" + @JIBUN1 + "is."
p "Parents" + @@JIBUN2 + "is."
p "Parents" + (@JIBUN3 || 'undefined') + "is."
end
end
#Child class
class Child < Parent
@JIBUN1 = "Child 1"
@@JIBUN2 = "Child 2"
def initialize
super
@JIBUN3 = "Child 3"
end
def print2
p "print2"
p "Children" + (@JIBUN1 || 'undefined') + "is."
p "Children" + (@@JIBUN2 || 'undefined') + "is."
p "Children" + @JIBUN3 + "is."
end
def self.print3
p "print3"
p "Children" + (@JIBUN1 || 'undefined') + "is."
p "Children" + (@@JIBUN2 || 'undefined') + "is."
p "Children" + (@JIBUN3 || 'undefined') + "is."
end
end
main
Execution result
"print"
"I am undefined."
"I am 2 kids"
"I am 3 kids"
"print2"
"Children are undefined."
"The child is child 2."
"The child is child 3."
"print3"
"The child is child 1."
"The child is child 2."
"Children are undefined."
"print"
"I am undefined."
"I am 2 kids"
"I'm parent 3"
"print2"
"The parent is undefined."
"The parent is child 2."
"The parent is parent 3."
"print3"
"The parent is parent 1."
"The parent is child 2."
"The parent is undefined."
The results are summarized below.
It seems that it was designed with classes, but it is a mystery why class variables and class instance variables became like this.