Ein Java-Ingenieur verglich Swift, Kotlin und Java.

Ich halte eine interne Kotlin-Lernsitzung ab und frage mich oft, was passiert, wenn ich Kotlins Grammatik in Swift und Java schreibe. Daher möchte ich die Ergebnisse der Implementierung untersuchen und zeichnen. .. Da es sich um eine andere Sprache handelt, kann es schwierig sein, eine strikte Gleichstellung vorzunehmen, aber bitte verzeihen Sie mir.

Überprüfung der Übergabe durch Referenz

Kotlin Ich habe in einer internen Studiensitzung darüber gesprochen, wie Pass-by-Reference in Kotlin implementiert werden kann, und habe daher eine kleine Überprüfung versucht.

Es scheint, dass Kotlin nicht als Referenz verwendet werden kann, es sei denn, es wird ausdrücklich als veränderlich deklariert. Wenn Sie versuchen, es einem Argument zuzuweisen, tritt ein Kompilierungsfehler auf.

ArrayTest.kt


fun addArray(array: MutableList<Int>) {
    array.add(9)
    println(array) // [1, 2, 3, 9]
}

fun changeArray(array: MutableList<Int>) {
    array = mutableListOf(1, 2, 3) //Es kann keinem Argument zugeordnet werden. Ein Kompilierungsfehler wird auftreten.
    println(array)
}

fun main(args: Array<String>) {
    val array = mutableListOf(1, 2, 3)
    println(array) // [1, 2, 3]
    addArray(array)
    println(array) // [1, 2, 3, 9]
}

Swift Swift kann durchgeführt werden, indem inout deklariert wird, dass es als Referenz übergeben wird. Da es als Referenz übergeben wird, kann die Array-Variable in der Funktion neu geschrieben werden.

ArrayTest.swift


func addArray(array : inout [Int])  {
    array.append(9)
    print(array)  // [1, 2, 3, 9]
}

func substituteArray(array : inout [Int])  {
    array = [100, 200, 300]
    print(array)  //  [100, 200, 300]
}

var array = [1, 2, 3]
print(array)    // [1, 2, 3]
addArray(array: &array)
print(array)    // [1, 2, 3, 9]
substituteArray(array: &array)
print(array)    // [100, 200, 300]

Java Ich habe versucht, dasselbe in Java zu tun, aber ich kann Änderungen mit der Array-Methode vornehmen. Das von der ursprünglichen Variablen angegebene Array hat sich auch dann nicht geändert, wenn es neu instanziiert und in der Referenzmethode zugewiesen wurde.

ArrayTest.java


import java.util.ArrayList;

class ArrayTest {
    private static void addArray(ArrayList<Integer> array) {
        array.add(9);
        System.out.println(array); // [1, 2, 3, 9]
    }

    private static void substituteArray(ArrayList<Integer> array) {
        array = new ArrayList<Integer>(); //Durch das Ersetzen einer neuen ArrayList wird der ursprüngliche Bereich nicht geändert.
        array.add(100);
        array.add(200);
        array.add(300);
        System.out.println(array); // [100, 200, 300]
    }

    public static void main(String args[]) {
        ArrayList<Integer> array = new ArrayList<Integer>();
        array.add(1);
        array.add(2);
        array.add(3);
        System.out.println(array); // [1, 2, 3]
        addArray(array);
        System.out.println(array); // [1, 2, 3, 9]
        substituteArray(array);
        System.out.println(array); // [1, 2, 3, 9]([100, 200, 300]Wird nicht sein)
    }
}

Schnittstelle

Kotlin Ich dachte, dass sich die Verwendung der Kotlin-Oberfläche nicht besonders von Java unterscheidet, aber ich denke, dass sie sich von Java darin unterscheidet, dass Feldvariablen ebenfalls eingeschränkt werden können.

InterfaceTest.kt



interface Lang {
    val name: String
    fun getHelloWorld(target: String) : String
}

class English : Lang {
    override val name = "English" //Kompilierungsfehler, wenn nicht deklariert
    override fun getHelloWorld(target: String) : String {
        return "Hello, $target!"
    }
}

class Japanese : Lang {
    override val name = "japanisch"
    override fun getHelloWorld(target: String) : String {
        return "Hallo,$target!"
    }
}

fun main(args: Array<String>) {
        val Elang = English()
    println(Elang.getHelloWorld("world")) // Hello, world!
    val Jlang = Japanese()
    println(Jlang.getHelloWorld("world")) //Hallo Welt!
    
}

Swift Im Fall von Swift scheint das Protokoll wie die Kotlin-Schnittstelle implementiert werden zu können.

InterfaceTest.swift


protocol Lang {
    var name : String {get}
    func getHelloWorld(target :String) -> String
}

class English: Lang {
    
    let name = "English"
    func getHelloWorld(target : String)  -> String {
        return "Hello, \(target)"
    }
}

class Japanese: Lang {
    
    let name = "Japanese"
    func getHelloWorld(target : String)  -> String {
        return "Hallo, \(target)"
    }
}

let Elang = English()
print(Elang.getHelloWorld(target: "world")) // Hello, world!
let Jlang = Japanese()
print(Jlang.getHelloWorld(target: "world")) //Hallo, world

Java Ich habe es nicht bemerkt, weil ich es nicht wirklich so verwenden wollte, aber Java kann eine tatsächliche Klasse nicht zwingen, ein Feld zu haben, wenn es ein Feld in Interface definiert. (Vielmehr wird es gezwungen sein, ein öffentliches Finale zu sein, daher wird es nur als Konstante behandelt.)

Lang.java


interface Lang {
    public static final String name = ""; //Die in der Schnittstelle definierten Felder müssen öffentlich staic final sein.
    public String getHelloWorld(String target);
}

English.java


class English implements Lang {
    // public String name; //OK ohne zu erklären

    @Override
    public String getHelloWorld(String target) {
        return "Hello, %TARGET%!".replace("%TARGET%", target);
    }
}

Japanese.java


class Japanese implements Lang {

    @Override
    public String getHelloWorld(String target) {
        return "Hallo, %TARGET%!".replace("%TARGET%", target);
    }
}

InterfaceTest.java


class InterfaceTest {
    public static void main(String args[]) {
        English Elang = new English();
        System.out.println(Elang.getHelloWorld("world")); // Hello, world!
        Japanese Jlang = new Japanese();
        System.out.println(Jlang.getHelloWorld("world")); //Hallo, world
    }
}

Begleitobjekt

Kotlin Statischer Zugriff (statisch) in Java und anderen Sprachen kann in Kotlin mit Companion Object implementiert werden.

CompanionObjectTest.kt


interface Lang {
    val name: String
    fun getHelloWorld(target: String) : String
}

class English : Lang {
    override val name = "English"
    override fun getHelloWorld(target: String) : String {
        return "Hello, $target!"
    }
    companion object Factory { // Companion object
        fun create(): English = English()
    }
}

fun main(args: Array<String>) {
    val Egreeter = English.create() //Erstellen Sie eine englische Entität mit der Create-Methode
    println(Egreeter.getHelloWorld("world"))
}

Ich habe verschiedene Dinge ausprobiert, aber CompanionObject funktioniert wie folgt.


class English : Lang {
    override val name = "English"
    override fun getHelloWorld(target: String) : String {
        return "Hello, $target!"
    }
    companion object Factory { //Factory kann vorhanden sein oder nicht, ist jedoch erforderlich, um über Java auf das Begleitobjekt zuzugreifen.
        const val COMPANION_NAME = "Companion" //Sie können Konstanten definieren.
        val companionName = "test" //Sie können Feldvariablen deklarieren, auf die statisch zugegriffen werden kann, ohne const hinzuzufügen.
        fun create(): English = English()
        fun getNameCom(): String {
            // return name //Sie können nicht über Companion Object auf das englische Feld zugreifen.
            return companionName  //Auf Variablen im Begleitobjekt kann zugegriffen werden
        }
    }
}

Grundsätzlich scheint es empfehlenswert, es zu verwenden, wenn ein konstanter Wert oder ein Factory-Muster wie die create-Methode implementiert wird.

Swift Im Fall von Swift kann dasselbe Verhalten durch Deklarieren von statisch implementiert werden. Wenn überhaupt, ist dies leichter zu verstehen, als sich als Begleitobjekt zu merken.

StaticTest.swift


protocol Lang {
    var name : String {get}
    func getHelloWorld(target :String) -> String
}

class English: Lang {
    
    let name = "English"
    func getHelloWorld(target : String)  -> String {
        return "Hello, \(target)"
    }
    static var COMPANION_NAME = "Companion"
    static func create() -> English {
        return English()
    }
    static func getName() -> String {
        return name   //Auf Mitgliedsvariablen kann nicht über statische Funktionen zugegriffen werden.
    }

}

let Egreeter = English.create()
print(Egreeter.getHelloWorld(target: "world"))
print(English.COMPANION_NAME) //Da es sich um eine Konstante handelt, kann darauf zugegriffen werden

Java Java kann auf die gleiche Weise wie Swift erstellt werden.

Lang.java


interface Lang {
    public String getHelloWorld(String target);
}

English.java


class English implements Lang {
    public String name = "English";

    @Override
    public String getHelloWorld(String target) {
        return "Hello, %TARGET%!".replace("%TARGET%", target);
    }

    public static final String COMPANION_NAME = "Companion";

    public static English create(){
        return new English();
    }
    public static String getName() {
        return name; //Der Name einer nicht statischen Variablen kann nicht aus dem statischen Kontext referenziert werden. Es wird eine Fehlermeldung angezeigt.
    }
}

StaticTest.java


class StaticTest {
    public static void main(String args[]) {
        English Elang = English.create();
        System.out.println(Elang.getHelloWorld("world"));
        System.out.println(English.COMPANION_NAME);
    }
}

Klassenvererbung und Konstruktor

Kotlin Um herauszufinden, wie man Klassen erbt und wie man sie konstruiert, habe ich die England-Klasse und ihre abstrakte Klasse Country-Klasse erstellt und ihnen den Ländernamen, die Sprache und die Bevölkerung als Attribute gegeben. Außerdem sagte ich aus dem Land, dass ich Grüße und etwas Bevölkerung bekommen könnte, und übertrug die eigentliche Verarbeitung auf die eigentliche Klasse der Lang-Schnittstelle. (Ehrlich gesagt finde ich, dass das Klassendesign subtil ist ...)

ConstructorTest.kt


interface Lang {
    val name: String
    fun getHelloWorld(target: String) : String
    fun getPopulation(countryName: String, population : Int) : String
}

class English : Lang {
    override val name = "English"
    override fun getHelloWorld(target: String) : String {
        return "Hello, $target!"
    }
    override fun getPopulation(countryName: String, population : Int) : String {
        return "$countryName has a population of $population people."
    }
}

//Machen Sie die Basisklasse obligatorisch, indem Sie ihr den Namen des Landes, die Sprache und die Bevölkerungsattribute geben
abstract class Country (_name : String, _lang: Lang, _population: Int) {
    val name : String = _name
    val lang : Lang = _lang
    val population = _population
    fun getPopulation() : String {
        return lang.getPopulation(name, population)
    }
}

class England() : Country("England", English(), 53013000)

fun main(args: Array<String>) {
	val country = England()
    
    println(country.name)
    println(country.lang.getHelloWorld("world"))
    println(country.getPopulation())
  
}

Swift Ich habe es in Swift umgeschrieben, aber ich dachte nicht, dass es notwendig ist, die Country-Klasse zu implementieren, da Swift nicht die Idee einer abstrakten Klasse hat. Ich empfehle nicht, Protokoll als Typ zu verwenden (können Sie das nicht sagen?), Also habe ich die Oberklasse gezwungen, keine lang-Eigenschaft zu haben.

ConstructorTest.kt


import Foundation

protocol Lang {
    var name : String {get}
    func getHelloWorld(target :String) -> String
    func getPopulation(countryName: String, population : Int) -> String
}

class English: Lang {
    
    let name = "English"
    func getHelloWorld(target : String)  -> String {
        return "Hello, \(target)"
    }
    
    func getPopulation(countryName: String, population : Int) -> String {
        return "\(countryName) has a population of \(population) people."
    }
}
class Country {
    var name : String = ""
    var population : Int = 0
    init(_name : String, _population : Int) {
        name = _name
        population = _population
    }
}

class England : Country {
    var lang = English()
    
     init() {
        super.init(_name: "England", _population: 53013000)
    }
    
    func getPopulation() -> String {
        return self.lang.getPopulation(countryName: name, population: population)
    }
    
    func getHelloWorld(target: String) -> String {
        return self.lang.getHelloWorld(target: target)
    }
}

var country = England()

print(country.name)
print(country.getHelloWorld(target: "world"))
print(country.getPopulation())

Java Es ist im Grunde dasselbe wie Kotlin, aber der Eigenschaftszugriff wird gemäß der Java-Methode in Getter geändert. Ich denke, dass der Code um diesen Betrag länger als Kotlin ist.

Lang.java


interface Lang {
    public String getHelloWorld(String target);
    public String getPopulation(String countryName, int population);
}

English.java


class English implements Lang {
    
    private String name = "English";

    public String getName() {
         return name;
    }

    @Override
    public String getHelloWorld(String target) {
        return "Hello, %TARGET%!".replace("%TARGET%", target);
    }

    @Override
    public String getPopulation(String countryName, int population) {
	return  "%COUNTRY_NAME% has a population of %POPULATION% people."
	    .replace("%COUNTRY_NAME%", countryName)
	    .replace("%POPULATION%", Integer.toString(population));
    }

}

Country.java


public abstract class Country {
    private String name;
    private Lang lang;
    private int population;

    public Country(String _name, Lang _lang, int _population) {
        name = _name;
        lang = _lang;
        population = _population;
    }

    public String getPopulation() {
        return lang.getPopulation(name, population);
    }

    public String getName() {
        return name;
    }

    public Lang getLang() {
        return lang;
    }

}

England.java


public class England extends Country {

    public static final String NAME = "England";
    public static final int POPULATION = 53013000;

    public England() {
        super(NAME, new English(), POPULATION);
    }
}

ConstructorTest.java


class ConstructorTest {

    public static void main(String args[]) {
        England country = new England();

        System.out.println(country.getName());
        System.out.println(country.getLang().getHelloWorld("world"));
        System.out.println(country.getPopulation());
    }
}

Null sicher

Ich werde von nun an schreiben.

Recommended Posts

Ein Java-Ingenieur verglich Swift, Kotlin und Java.
Schreiben Sie eine Klasse in Kotlin und nennen Sie sie in Java
Ich möchte eine Liste mit Kotlin und Java erstellen!
Ich möchte eine Funktion mit Kotlin und Java erstellen!
Ich habe PHP- und Java-Konstruktoren verglichen
Unterschiede zwischen "Anfänger" Java und Kotlin
Ich habe Java und Rubys FizzBuzz verglichen.
[Java] Erstellen und Anwenden eines Folienmasters
Konvertierung zwischen Kotlin nullable und Java Optional
Ein Blick auf Jenkins, OpenJDK 8 und Java 11
Beziehung zwischen Kotlin- und Java-Zugriffsmodifikatoren
[Swift] Ein Hinweis zu Funktion und Schließung
[Für Anfänger] Unterschied zwischen Java und Kotlin
[Java / Swift] Vergleich von Java-Schnittstelle und Swift-Protokoll
Kotlin-Funktionen und Lambdas zum Senden an Java-Entwickler
Java switch Anweisung und break, Kotlin beim Ausdruck ...
[Swift vs Java] Lassen Sie uns statisch und endgültig verstehen
Ich habe die Eigenschaften von Java und .NET verglichen
Vergleich zwischen Java und Swift (1) Quellcodeverwaltung / Umfang / Variablen
Java und JavaScript
XXE und Java
Bereiten Sie eine Scraping-Umgebung mit Docker und Java vor
Java- und Swift-Vergleich (3) Klassenimplementierung / Klassenvererbung / Klassendesign
Bitte beachten Sie die Aufteilung (Aufteilung) von Java Kotlin Int und Int
Senden Sie mir eine Roadmap, um ein vollwertiger Java-Ingenieur zu werden
Rufen Sie eine Methode mit Kotlins Rückrufblock von Java aus auf
Java-Sprache aus der Sicht von Kotlin und C #
Ich möchte Bildschirmübergänge mit Kotlin und Java machen!
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
Rufen Sie ein in Swift geschriebenes Programm von Processing (Java) auf.
Erstellen Sie eine JAVA WEB App und probieren Sie OMC APM aus
[Java] [Kotlin] Rufen Sie valueOf und Werte von Enum generisch auf
[Java] Erstellen Sie einen Filter
Java wahr und falsch
[Java] Vergleich von Zeichenketten und && und ||
Java baut ein Dreieck
[Java, Kotlin] Typabweichung
Java - Serialisierung und Deserialisierung
[Java] Argumente und Parameter
timedatectl und Java TimeZone
[Java] Verzweigen und Wiederholen
[Java] Variablen- und Typtypen
Java (Klasse und Instanz)
[Java] Überladen und überschreiben
Weisen Sie Variablen Java8-Lambda-Ausdrücke zu und verwenden Sie sie erneut
Memorandum Nr. 4 "Holen Sie sich eine Zeichenkette und dekorieren Sie sie" [Java]
[Java] Wirf eine Anfrage und zeige den Bildschirm ② (GET / POST) an.
Ich habe versucht, die Grundlagen von Kotlin und Java zusammenzufassen
[Java] Wirf eine Anfrage und zeige den Bildschirm an (GET / POST)
[Kotlin] Ressourcen und Tipps zum Erlernen einer neuen Programmiersprache
Kotlin Post- und Pre-Inkrement und Operatorüberladung (Vergleich mit C, Java, C ++)
[Kotlin] Holen Sie sich Java Constructor / Method von KFunction und rufen Sie es auf
So stellen Sie eine Kotlin (Java) -App auf AWS fargate bereit
Java-Sprachfunktion und wie sie einen subtilen Fehler verursachte
Gleiches Urteil / gleichwertiges Urteil / Vergleich / Reihenfolge in Swift und Java
Fügen Sie dem Swift-Button (und auch dem Kreis) einen Schatten hinzu.
So entwickeln und registrieren Sie eine Sota-App in Java