Cet article est une compilation des résultats de mes recherches sur les valeurs réellement générées en écrivant l'héritage de classe dans différentes langues de la même manière. Parfois, je travaillais dur depuis Hello World, pensant qu'il y avait une telle grammaire même dans une langue connue.
Qui gagnerait à ce que ce soit difficile à assembler? Cependant, je laisserai cela à ceux qui s'intéressent à la même chose. Non, il peut y avoir de nouvelles découvertes, alors veuillez le lire pour le moment. Cela a peut-être été un résultat étonnamment intéressant.
Saisie statique
Java (Corretto 1.8.0_232)
C# (3.4.0)
C++ (11.0.0)
Scala (2.13.1)
Kotlin (1.3.61)
Swift (5.1.3)
Typage dynamique
Python (3.7.1)
Ruby (2.6.5)
PHP (7.1.32)
JavaScript (node v12.14.1)
Typage statique en option
TypeScript (3.7.2)
Dart (2.7.0)
Une classe enfant hérite d'une classe parent. Ses classes parent et enfant ont des variables d'instance avec le même nom. (Pas une variable de classe) La classe parente a une méthode qui vous permet de générer des variables d'instance vers la console.
Au moment de l'exécution, l'instance de classe enfant appelle la méthode parent héritée. Maintenant, l'histoire est ** Quelle variable d'instance sera sortie, parent ou enfant? ** …….
Si vous l'écrivez dans un code JS (ES6 ou ultérieur) que de nombreuses personnes peuvent probablement lire, c'est un tel code.
class SuperClass {
constructor() {
//* Dans JS, les variables d'instance sont définies à l'exécution, donc écrivez-les dans le constructeur.
this.instanceVariable = "SuperClass" //Différentes valeurs avec le même nom
}
superClassMethod() {
console.log(this.instanceVariable)
}
}
class SubClass extends SuperClass {
constructor() {
super()
this.instanceVariable = "SubClass" //Différentes valeurs avec le même nom
}
}
const sub = new SubClass() //Intensifier la classe enfant
sub.superClassMethod() //Appelez la méthode de classe parent héritée
Imaginez quelles valeurs sont affichées dans la langue que vous utilisez normalement. C'est un style d'écriture occasionnel (bon ou mauvais), donc vous savez peut-être dans quoi vous êtes bon. Mais si vous savez comment cela fonctionne dans d'autres langues, cela peut être utile un jour lorsque vous entrez dans une autre entreprise ou un projet différent, ou lorsque vous souhaitez vous lancer dans une autre langue.
Cette fois, je regarde non seulement les variables d'instance mais aussi ce qui se passe lorsque vous retournez "SuperClass" `avec une méthode (une méthode d'une instance qui n'est pas une méthode de classe). Dans ce cas, la classe parent et la classe enfant ont une méthode avec le même nom et la méthode de la classe parent l'appelle ....
Vous pouvez découvrir quel code vous avez écrit et recherché
<détails> Puisque l'élément de pliage détaillé est placé comme ceci, vous pouvez lire le code à l'intérieur en cliquant dessus pour l'ouvrir.
C'est un joli code WET qui utilise en principe le copier-coller pour vous permettre de voir plus facilement ce que vous faites, mais ne lancez pas Masakari parce que c'est intentionnel. Comme vous le savez, différents langages de programmation ont différentes grammaires et différentes méthodes d'évaluation.
Je pense que les points qui changeront les résultats cette fois sont les suivants. Java Java, le champion des systèmes d'entreprise.
Java a des modificateurs d'accès tels que «privé» et «protégé».
Il n'y a pas de remplacement de variable d'instance en Java.
Voyons donc ce qui se passe lorsque nous le remplaçons par une méthode. Remplace littéralement «écraser». Cette fois, cela n'avait pas d'importance, mais Java vous permet d'accéder aux variables d'instance de la classe parent avec des méthodes du côté de la classe enfant comme <détails> C# Après Java, C #. Il a une grammaire assez proche de Java pour des raisons historiques. Le résultat est également similaire à Java et C ++ décrit ci-dessous, mais il y en a que Java n'a pas.
Au fait, C # a des propriétés, donc je les ai écrites comme des propriétés au lieu de méthodes. C # a C'est bien, mais C # a aussi un modificateur étrange appelé <détails> C++ Il semble que C ++ soit souvent utilisé dans le domaine de l'incorporation, mais je ne sais rien.
C ++ Nanimowa Karanai ……. Avec Java, c'est le langage original de C # et son comportement est très similaire à C #.
Si vous utilisez une méthode au lieu d'une variable d'instance et que vous ne la remplacez pas, elle se comporte de la même manière que <détails> Scala AltJava qui intègre un style fonctionnel.
La grande différence entre Java et C # est que vous pouvez ** remplacer les variables d'instance **. Les nouvelles fonctionnalités sont là! <détails> Kotlin Alt Java a été fortement influencé par Scala. Il est souvent utilisé dans le développement d'applications Android.
Identique à Scala, sauf que la variable d'instance que vous prévoyez de remplacer doit être ouverte.
Donc ʻopen <détails> Swift Android n'est pas la seule application. Je ne veux pas que vous oubliez iOS.
Il semble que le comportement de "private" de Swift change en fonction de la version, mais cette fois je l'ai vérifié avec Swift 5, donc comme Java, il n'est valide que dans la classe et n'est pas hérité. «Let» de Swift est une déclaration de variable qui interdit la réaffectation. Dans JS, c'est Dans Swift, vous ne pouvez pas définir une variable d'instance (appelée propriété dans Swift) qui est la même que la source d'héritage.
Vous pouvez le remplacer en utilisant la propriété calculée (comme une propriété en C #) à la place. Sans un modificateur d'accès tel que <détails> Python A partir de là, un langage typé dynamiquement!
Python a rendu sa popularité solide, en continuant à occuper la première place dans le classement des publications d'étiquettes de Qiita. La caractéristique des classes Python est que l'instance elle-même arrive au premier argument de la méthode, donc lorsque vous la déclarez, écrivez Après cela, comme un langage typé dynamiquement, les variables d'instance sont créées dynamiquement, définissez donc les variables d'instance dans le constructeur plutôt que directement sous la déclaration de classe. C'est la même chose pour Ruby et JavaScript. Python n'a aucune restriction d'accès aux membres. Il n'y a pas de modificateur «privé».
C'est une culture qui préfixe le nom de la fonction avec ** 1 ** pour indiquer que vous ne souhaitez pas y accéder. Mais en Python, il existe une fonctionnalité au cas où il y aurait un conflit de nom avec une classe enfant. L'ajout de ** 2 ** souligne modifie le nom du membre interne (modification du nom) et facilite l'accès au nom de la variable d'origine. Cette fonctionnalité vous permet d'évaluer les résultats lors de l'exécution dans le contexte de la classe parent d'origine, même si la classe enfant a des membres portant le même nom.
pep8-ja - convention de dénomination - nom de méthode et variable d'instance
Voyons le résultat. <détails> Ruby "Qu'en est-il d'un langage à typage dynamique orienté objet?"
De nombreux programmeurs qui ont répondu au quiz associatif pensent en premier à ce langage. Ruby a un À propos, dans Ruby, les espaces de noms des variables et des méthodes sont séparés, vous pouvez donc les appeler même si vous écrivez la méthode sans parenthèses.
La méthode retourne ensuite le résultat de la dernière expression évaluée sans écrire de retour.
<détails> PHP PHP a <détails> JavaScript Le champion du front-end.
Un langage orienté objet basé sur un prototype, un langage inspiré du langage de programmation Self.
Étant donné que ES6 et les versions ultérieures JavaScript incorporent également l'écriture basée sur les classes, elles peuvent être héritées par ʻextends`. <détails> TypeScript C'est un JavaScript cool qui peut être typé statiquement.
Il existe des types d'union, qui sont similaires aux types trouvés dans Haskell, qui a un système de type avancé, et il existe des types conditionnels, des types mappés et d'autres types expressifs. Dans TypeScript, la définition d'un membre avec le même nom que <détails> Dart C'est une langue impressionnante qui a soudainement une présence depuis que Flutter est devenu populaire.
Dart n'écrit pas «privé» ou «public». Vous pouvez le rendre privé en ajoutant un trait de soulignement au nom du membre, mais il est différent de <détails> C'était étonnamment amusant parce qu'il y avait des choses que je ne savais même pas dans une langue dans laquelle j'étais habitué dans une certaine mesure.
Certains des exemples que j'ai écrits pour la première fois cette fois, voici comment les écrire! Ou quelque chose ne va pas! Veuillez commenter si vous en avez. Dans l'ensemble, j'avais l'impression que dans un langage typé dynamiquement, même lorsqu'une méthode de superclasse était appelée, elle serait d'abord évaluée dans le contexte d'une sous-classe. D'un autre côté, dans le langage typé statiquement, c'était comme: "Parce que c'est une méthode d'une superclasse, les bases sont évaluées par la superclasse, mais si vous la remplacez, ce n'est pas le cas." Les cinq suivants étaient personnellement impressionnants. --C # a un modificateur non prioritaire appelé
Recommended Posts
class Hoge {}
Le point de cette fois
Annonce des résultats
private
ne peut être vu que depuis la classe courante. protected
est accessible depuis la classe actuelle et les classes enfants.
conditions
résultat
La variable d'instance est privée
"SuperClass"
Les variables d'instance sont protégées
"SuperClass"
Méthode privée au lieu de la variable d'instance
"SuperClass"
Méthode protégée (remplacement) au lieu de la variable d'instance
"SubClass"
super.instanceVariable
. C'est une astuce que vous pouvez faire parce que vous ne la remplacez pas.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 {
//Les variables d'instance privée ne peuvent pas être référencées par des sous-classes
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);Si vous écrivez
// System.out.println(this.instanceVariable);Pareil que."SubClass"sortir.
//Avec super,"SuperClass"Peut également être affiché
// 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";
}
}
virtual
et ʻoverride.
virtual est un modificateur qui vous indique que cette méthode peut être surchargée, et ʻoverride
est un modificateur qui vous indique que la méthode est remplacée ici.new
. Ce nouveau est différent du nouveau du «nouvel Humain ()» au moment de l'instanciation. En ajoutant new au lieu de override, la méthode de la classe parent peut être évaluée dans le contexte de la classe parent même si elle est appelée depuis une classe enfant. La raison est que nous ne remplaçons pas les méthodes de la classe parente, nous les cachons simplement. C'est compliqué.
conditions
résultat
La variable d'instance est privée
"SuperClass"
Les variables d'instance sont protégées
"SuperClass"
La propriété est privée
"SuperClass"
Propriété protégée(override)
"SubClass"
Propriété protégée(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 n'est pas un remplacement, il indique explicitement qu'il masque la variable d'instance héritée
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";
}
}
}
new
en C #.
conditions
résultat
La variable d'instance est privée
"SuperClass"
Les variables d'instance sont protégées
"SuperClass"
Méthode privée au lieu de la variable d'instance
"SuperClass"
Méthode protégée (remplacement) au lieu de la variable d'instance
"SubClass"
Méthode protégée au lieu de la variable d'instance (ne pas remplacer)
"SuperClass"
#include <iostream>
class SuperClass {
//Privé par défaut (inaccessible de l'extérieur de la classe)
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;
}
conditions
résultat
La variable d'instance est privée
"SuperClass"
Variable d'instance protégée (remplacement)
"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";
}
est comme
virtual` en C ++ ou C #.
conditions
résultat
La variable d'instance est privée
"SuperClass"
Variable d'instance protégée (remplacement)
"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";
}
const
.
Et «var» de Swift est une déclaration de variable réassignable normale. C'est «let» dans JS. C'est compliqué.private
, la portée sera ʻinternal. ʻInternal
est comme public
en Java (divers).
conditions
résultat
La variable d'instance est privée
"SuperClass"
La variable d'instance est interne
Indéfinissable
La propriété calculée est privée
"SuperClass"
La propriété calculée est interne(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";
}
// --------------------------------
//Faites-en une propriété calculée et développez un getter. Dans ce cas, il est traité comme une fonction, vous pouvez donc le remplacer.
class SuperClassGetter {
//Si c'est laissé, erreur: '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" } };
}
// --------------------------------
//Faites-en une propriété calculée et développez un getter. Dans ce cas, il est traité comme une fonction, vous pouvez donc le remplacer.
class SuperClassInternalGetter {
//Si c'est laissé, erreur: '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();
self
comme premier argument. Il n'est pas nécessaire que ce soit «soi», mais tout le monde s'écrit «soi».
conditions
résultat
Variable d'instance
"SubClass"
Méthode au lieu de la variable d'instance
"SubClass"
Variable d'instance (avec 2 Ansco)
"SuperClass"
Méthode au lieu de variable d'instance (avec 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()
privé
que vous pouvez utiliser pour les méthodes, mais il se comporte différemment d'un langage comme Java. Je ne l'écrirai pas en détail car je dois expliquer le récepteur etc., mais pour le moment, je peux dire que même s'il y a «private», la méthode peut être vue dans la destination d'héritage. Donc, en Java, «protected» peut être plus proche.
[Ruby] L'essence des méthodes privées et les avantages de les comprendre@ Variagename
est la variable d'instance. Dans Ruby, vous pouvez indiquer le type (portée) d'une variable par le premier caractère du nom de la variable.
conditions
résultat
Variable d'instance
"SubClass"
Méthode au lieu de la variable d'instance
"SubClass"
Méthode privée au lieu de la variable d'instance
"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
private
, protected
et public
comme Java.
Ce n'est fondamentalement pas en Python, Ruby ou JavaScript! Jaloux!
Mais contrairement à Java, les variables d'instance protected
vont lire les sous-classes.
C'est un mouvement qui est en ligne avec d'autres langages typés dynamiquement.
conditions
résultat
La variable d'instance est privée
"SuperClass"
Les variables d'instance sont protégées
"SubClass"
Méthode privée au lieu de la variable d'instance
"SuperClass"
Méthode protégée au lieu de la variable d'instance
"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();
conditions
résultat
Variable d'instance
"SubClass"
Variables d'instance dans l'ancien format
"SubClass"
Dans la variable d'instance, la méthode d'appel est une fonction de flèche
"SubClass"
Fonction de flèche au lieu de variable d'instance
"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()
private
dans une classe parent et une classe enfant entraînera une erreur de compilation. S'il est "protégé", il n'y a pas de problème. C'est exactement le contraire de Swift.
conditions
résultat
La variable d'instance est privée
Indéfinissable
Les variables d'instance sont protégées
"SubClass"
Méthode privée au lieu de la variable d'instance
Indéfinissable
La variable d'instance est protégée et la méthode d'appel est une fonction fléchée
"SubClass"
Fonction de flèche protégée au lieu de variable d'instance
"SubClass"
class SuperClass {
private readonly instanceVariable: string
constructor() {
this.instanceVariable = "Error"
}
public superClassMethod() {
console.log(this.instanceVariable)
}
}
class SubClass extends SuperClass {
//Lorsque vous essayez de définir avec 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 {
//Lorsque vous essayez de définir avec 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"
}
}
// ------------------------
//Version de la fonction flèche
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()
private
tel que Java car il ne le rend invisible que de l'extérieur de la bibliothèque.
conditions
résultat
Variable d'instance (avec ansco)
"SubClass"
Variable d'instance
"SubClass"
Méthode au lieu de la variable d'instance
"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 {
//Si vous donnez un trait de soulignement, ce sera Privé,
//Puisque private est visible dans la même bibliothèque, cela semble normal à partir de la sous-classe ici
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";
}
Résumé
nouveau
--Scala et Kotlin sont des langages typés statiquement mais peuvent remplacer les variables d'instance
--Python souligné Les deux noms de membres étaient plus que de simples noms, ils avaient aussi un effet
--PHP a un privé
comme Java même s'il s'agit d'un langage typé dynamiquement
--TypeScript empêche les membres privés
en double avec le même nom de provoquer une erreur au moment de la compilation et de provoquer un comportement inattendu.Journal des modifications