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.
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)
}
}
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
}
}
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);
}
}
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());
}
}
Ich werde von nun an schreiben.
Recommended Posts