Je tiens une session d'étude Kotlin en interne, et je me demande souvent ce qui se passe lorsque j'écris la grammaire de Kotlin en Swift et Java, alors j'aimerais étudier et dessiner les résultats de l'implémentation. .. C'est une langue différente, donc je pense qu'il est difficile d'être un égal strict, mais pardonnez-moi s'il vous plaît.
Kotlin J'ai parlé de la façon de mettre en œuvre le passage par référence dans Kotlin lors d'une session d'étude en interne, alors j'ai essayé une petite vérification.
Il semble que Kotlin ne peut pas être utilisé par référence à moins qu'il ne soit explicitement déclaré mutable. De plus, si vous essayez de l'attribuer à un argument, une erreur de compilation se produira.
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) //Il ne peut pas être attribué à un argument. Une erreur de compilation se produira.
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 peut être fait en déclarant inout qu'il est passé par référence. Puisqu'elle est passée par référence, la variable tableau peut être réécrite dans la fonction.
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 J'ai essayé de faire la même chose en Java, mais je peux apporter des modifications en utilisant la méthode array, Le tableau affiché par la variable d'origine n'a pas changé même s'il a été nouvellement instancié et affecté dans la méthode de référence.
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>(); //Remplacer ici une nouvelle ArrayList ne modifie pas la portée d'origine.
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]Ne sera pas)
}
}
Kotlin Je pensais que l'utilisation de l'interface de Kotlin n'est pas particulièrement différente de Java, mais je pense qu'elle est différente de Java dans le sens où les variables de champ peuvent également être restreintes.
InterfaceTest.kt
interface Lang {
val name: String
fun getHelloWorld(target: String) : String
}
class English : Lang {
override val name = "English" //Erreur de compilation si non déclarée
override fun getHelloWorld(target: String) : String {
return "Hello, $target!"
}
}
class Japanese : Lang {
override val name = "Japonais"
override fun getHelloWorld(target: String) : String {
return "Bonjour,$target!"
}
}
fun main(args: Array<String>) {
val Elang = English()
println(Elang.getHelloWorld("world")) // Hello, world!
val Jlang = Japanese()
println(Jlang.getHelloWorld("world")) //Bonjour le monde!
}
Swift Dans le cas de Swift, il semble que Protocol puisse être implémenté comme l'interface Kotlin.
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 "Bonjour, \(target)"
}
}
let Elang = English()
print(Elang.getHelloWorld(target: "world")) // Hello, world!
let Jlang = Japanese()
print(Jlang.getHelloWorld(target: "world")) //Bonjour, world
Java Je ne m'en suis pas rendu compte parce que je ne voulais pas vraiment l'utiliser de cette façon, mais Java ne peut pas forcer une classe réelle à avoir un champ lorsqu'elle définit un champ dans Interface. (Au contraire, il sera forcé d'être une finale staique publique, il sera donc traité comme une constante.)
Lang.java
interface Lang {
public static final String name = ""; //Les champs définis dans l'interface sont forcés d'être public staic final.
public String getHelloWorld(String target);
}
English.java
class English implements Lang {
// public String name; //OK sans déclarer
@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 "Bonjour, %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")); //Bonjour, world
}
}
Kotlin L'accès statique (statique) en Java et dans d'autres langages peut être implémenté dans Kotlin avec Companion Object.
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() //Créer une entité anglaise avec la méthode Create
println(Egreeter.getHelloWorld("world"))
}
J'ai essayé diverses choses, mais CompanionObject fonctionne comme suit.
--Un CompanionObject peut être défini dans une classe
class English : Lang {
override val name = "English"
override fun getHelloWorld(target: String) : String {
return "Hello, $target!"
}
companion object Factory { //Factory peut être présent ou non, mais requis pour accéder à l'objet compagnon depuis java.
const val COMPANION_NAME = "Companion" //Vous pouvez définir des constantes.
val companionName = "test" //Vous pouvez déclarer des variables de champ accessibles statiquement sans ajouter de const.
fun create(): English = English()
fun getNameCom(): String {
// return name //Vous ne pouvez pas accéder au champ anglais depuis l'objet compagnon.
return companionName //Les variables de l'objet compagnon sont accessibles
}
}
}
Fondamentalement, il semble être recommandé de l'utiliser lors de l'implémentation d'une valeur constante ou d'un modèle Factory tel que la méthode create.
Swift Dans le cas de Swift, le même comportement peut être implémenté en déclarant static. En fait, c'est plus facile à comprendre que de s'en souvenir comme un objet compagnon.
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 //Les variables membres ne sont pas accessibles à partir des fonctions statiques.
}
}
let Egreeter = English.create()
print(Egreeter.getHelloWorld(target: "world"))
print(English.COMPANION_NAME) //Puisqu'il s'agit d'une constante, on peut y accéder
Java Java peut être construit de la même manière que Swift.
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; //Le nom de la variable non statique ne peut pas être référencé à partir du contexte statique. J'obtiens une erreur.
}
}
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 Pour savoir comment hériter des classes et comment les construire, j'ai créé la classe England et sa classe abstraite Country class, et leur ai donné le nom du pays, la langue et la population comme attributs. De plus, du pays, j'ai dit que je pouvais recevoir des salutations et de la population, et j'ai transféré le traitement réel à la classe réelle de l'interface Lang. (Honnêtement, je pense que la conception de la classe est subtile ...)
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."
}
}
//Rendre la classe de base obligatoire en lui donnant le nom du pays, la langue et les attributs de population
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 J'ai essayé de le réécrire dans Swift, mais je ne pensais pas que Swift avait l'idée d'une classe abstraite, donc je ne pensais pas qu'il était vraiment nécessaire d'implémenter la classe Country. Je ne recommande pas d'utiliser Protocol comme type (ne pouvez-vous pas dire ça?), J'ai donc forcé la superclasse à ne pas avoir de propriété lang.
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 C'est fondamentalement le même que Kotlin, mais l'accès à la propriété est changé en getter selon la méthode Java. Je pense que le code est plus long que Kotlin de ce montant.
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());
}
}
J'écrirai désormais.
Recommended Posts