More puzzlers
This commit is contained in:
Generated
+1
@@ -3,6 +3,7 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/exPuzzlers.iml" filepath="$PROJECT_DIR$/exPuzzlers.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../../stdlib/stdlib.iml" filepath="$PROJECT_DIR$/../../stdlib/stdlib.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="stdlib" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -1,61 +1,36 @@
|
||||
namespace std
|
||||
|
||||
fun <T> array(vararg array : T) = array
|
||||
fun array(vararg array : Byte) = array
|
||||
fun array(vararg array : Char) = array
|
||||
fun array(vararg array : Short) = array
|
||||
fun array(vararg array : Int) = array
|
||||
fun array(vararg array : Long) = array
|
||||
fun array(vararg array : Double) = array
|
||||
fun array(vararg array : Float) = array
|
||||
inline fun <T> array(vararg array : T) = array
|
||||
inline fun array(vararg array : Byte) = array
|
||||
inline fun array(vararg array : Char) = array
|
||||
inline fun array(vararg array : Short) = array
|
||||
inline fun array(vararg array : Int) = array
|
||||
inline fun array(vararg array : Long) = array
|
||||
inline fun array(vararg array : Double) = array
|
||||
inline fun array(vararg array : Float) = array
|
||||
|
||||
fun Any?.identityEquals(other : Any?) = this === other
|
||||
|
||||
fun <T : Any> T?.npe() : T {
|
||||
inline fun <T : Any> T?.sure() : T {
|
||||
if (this == null)
|
||||
throw NullPointerException()
|
||||
return this;
|
||||
}
|
||||
|
||||
namespace io {
|
||||
import java.io.*
|
||||
|
||||
fun print(message : Any?) { System.out?.print(message) }
|
||||
fun print(message : Int) { System.out?.print(message) }
|
||||
fun print(message : Long) { System.out?.print(message) }
|
||||
fun print(message : Byte) { System.out?.print(message) }
|
||||
fun print(message : Short) { System.out?.print(message) }
|
||||
fun print(message : Char) { System.out?.print(message) }
|
||||
fun print(message : Boolean) { System.out?.print(message) }
|
||||
fun print(message : Float) { System.out?.print(message) }
|
||||
fun print(message : Double) { System.out?.print(message) }
|
||||
fun print(message : CharArray) { System.out?.print(message) }
|
||||
|
||||
fun println(message : Any?) { System.out?.println(message) }
|
||||
fun println(message : Int) { System.out?.println(message) }
|
||||
fun println(message : Long) { System.out?.println(message) }
|
||||
fun println(message : Byte) { System.out?.println(message) }
|
||||
fun println(message : Short) { System.out?.println(message) }
|
||||
fun println(message : Char) { System.out?.println(message) }
|
||||
fun println(message : Boolean) { System.out?.println(message) }
|
||||
fun println(message : Float) { System.out?.println(message) }
|
||||
fun println(message : Double) { System.out?.println(message) }
|
||||
fun println(message : CharArray) { System.out?.println(message) }
|
||||
|
||||
private var systemIn : InputStream? = null // Unfortunately, System.in may change
|
||||
private var stdin : BufferedReader? = null // This may introduce leaks of system.in objects...
|
||||
|
||||
fun readLine() : String? {
|
||||
if (stdin == null || systemIn != System.`in`) {
|
||||
stdin = java.io.BufferedReader(java.io.InputStreamReader(System.`in`))
|
||||
systemIn = System.`in`
|
||||
namespace string {
|
||||
fun String.replaceAllSubstrings(pattern : String, replacement : String) : String {
|
||||
return (this as java.lang.String).replace(pattern as CharSequence, replacement as CharSequence).sure()
|
||||
}
|
||||
return stdin?.readLine()
|
||||
|
||||
fun String.replaceAllWithRegex(pattern : String, replacement : String) : String {
|
||||
return (this as java.lang.String).replaceAll(pattern, replacement).sure()
|
||||
}
|
||||
}
|
||||
|
||||
namespace string {
|
||||
fun String.replaceAll(pattern : String, replacement : String) : String {
|
||||
return (this as java.lang.String).replace(pattern as CharSequence, replacement as CharSequence).npe()
|
||||
namespace jutils {
|
||||
|
||||
fun <T : Any> T.getJavaClass() : Class<T> {
|
||||
return ((this as Object).getClass()) as Class<T>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@ fun main(args : Array<String>) {
|
||||
)
|
||||
}
|
||||
|
||||
val String.bd = BigDecimal(this)
|
||||
val String.bd : BigDecimal get() = BigDecimal(this)
|
||||
|
||||
fun BigDecimal.minus(other : BigDecimal) = this.subtract(other)
|
||||
fun BigDecimal.minus(other : String) = subtract(other.bd) // this can be omitted
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
namespace whats.my.`class`
|
||||
|
||||
import std.io.*
|
||||
import std.*
|
||||
import std.string.*
|
||||
import typeinfo.*
|
||||
import std.jutils.*
|
||||
|
||||
class Me {
|
||||
class Me() {
|
||||
fun main() {
|
||||
(this as Object).getClass()?.getCanonicalName()?.replaceAll(".", "/")
|
||||
println(getJavaClass().getCanonicalName()?.replaceAllSubstrings(".", "/"))
|
||||
|
||||
// Regex is denoted explicitly
|
||||
println(getJavaClass().getCanonicalName()?.replaceAllWithRegex(".", "/"))
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
// Note: \u000A is Unicode representation of linefeed (LF)
|
||||
val c : Char = 0x000A .chr;
|
||||
println(c);
|
||||
Me().main()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package _03_character._21_Whats_My_Class_Take_2;
|
||||
|
||||
/**
|
||||
* Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 45). Pearson Education (USA). Kindle Edition.
|
||||
*/
|
||||
|
||||
public class MeToo {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(MeToo.class.getName().
|
||||
replaceAll("\\.", /*File.separator*/"\\") + ".class");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace whats.my.`class`.take2
|
||||
|
||||
import std.io.*
|
||||
import std.string.*
|
||||
import std.jutils.*
|
||||
import java.io.File;
|
||||
|
||||
class MeToo() {
|
||||
fun main() {
|
||||
println(getJavaClass().getCanonicalName()?.replaceAllSubstrings(".", /*File.separator.sure()*/"\\"))
|
||||
|
||||
// Regex is denoted explicitly
|
||||
println(getJavaClass().getCanonicalName()?.replaceAllWithRegex(".", "\\"))
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
MeToo().main()
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package _03_character._23_No_Pain_No_Gain;
|
||||
|
||||
/**
|
||||
* Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 49). Pearson Education (USA). Kindle Edition.
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Rhymes {
|
||||
private static Random rnd = new Random();
|
||||
|
||||
public static void main(String[] args) {
|
||||
StringBuffer word = null;
|
||||
switch (rnd.nextInt(2)) {
|
||||
case 1:
|
||||
word = new StringBuffer('P');
|
||||
case 2:
|
||||
word = new StringBuffer('G');
|
||||
default:
|
||||
word = new StringBuffer('M');
|
||||
}
|
||||
word.append('a');
|
||||
word.append('i');
|
||||
word.append('n');
|
||||
System.out.println(word);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace no.pain.no.gain
|
||||
|
||||
import std.io.*
|
||||
|
||||
val rnd = java.util.Random();
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
// The erroneous code does not compile:
|
||||
// var word : StringBuffer? = null
|
||||
// when (rnd.nextInt(2)) {
|
||||
// 1 => word = StringBuffer('P')
|
||||
// 2 => word = StringBuffer('G')
|
||||
// else => word = StringBuffer('M')
|
||||
// }
|
||||
// word?.append('a')
|
||||
// word?.append('i')
|
||||
// word?.append('n')
|
||||
// println(word)
|
||||
|
||||
// A natural implementation can't possibly have two problems out of three:
|
||||
// * fall-through cases
|
||||
// * StringBuffer(int) called with 'P'
|
||||
val word =
|
||||
when (rnd.nextInt(2)) {
|
||||
1 => StringBuffer().append('P')
|
||||
2 => StringBuffer().append('G')
|
||||
else => StringBuffer().append('M')
|
||||
}
|
||||
word?.append('a')
|
||||
word?.append('i')
|
||||
word?.append('n')
|
||||
println(word)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package _04_loopy._24_Big_Delight_in_Every_Byte;
|
||||
|
||||
/**
|
||||
* Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 53). Pearson Education (USA). Kindle Edition.
|
||||
*/
|
||||
public class BigDelight {
|
||||
public static void main(String[] args) {
|
||||
for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
|
||||
if (b == 0x90)
|
||||
System.out.print("Joy!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
namespace big.delight.in.every.byte
|
||||
|
||||
import std.io.*
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
// for (b : Byte in Byte.MIN_VALUE..Byte.MAX_VALUE) {
|
||||
// // Problematic code does not compile
|
||||
// if (b == 0x90 .byt)
|
||||
// println("joy")
|
||||
// }
|
||||
for (b : Byte in Byte.MIN_VALUE to Byte.MAX_VALUE) {
|
||||
// Problematic code does not compile
|
||||
if (b == 0x90 .byt)
|
||||
println("joy")
|
||||
}
|
||||
}
|
||||
|
||||
trait IntCompatible<T> {
|
||||
fun valueOf(i : Int) : T
|
||||
fun next(current : T) : T
|
||||
fun compareToInt(t : T, int : Int) : Int
|
||||
}
|
||||
|
||||
class NumberRange<T : Comparable<T>>(val from : Int, val to : Int) : Range<Int>, Iterable<T>
|
||||
where class object T : IntCompatible<T> {
|
||||
|
||||
override fun contains(item: Int) : Boolean = from <= item && item <= to
|
||||
fun contains(item: T) : Boolean = T.compareToInt(item, from) >= 0 && T.compareToInt(item, to) <= 0
|
||||
|
||||
override fun iterator(): Iterator<T> = object : Iterator<T> {
|
||||
private var current : T = T.valueOf(from)
|
||||
override fun next() : T {
|
||||
if (!hasNext) throw java.util.NoSuchElementException()
|
||||
val result = current
|
||||
current = T.next(current)
|
||||
return result
|
||||
}
|
||||
override val hasNext : Boolean
|
||||
get() = T.compareToInt(current, to) < 0
|
||||
}
|
||||
}
|
||||
|
||||
fun Byte.to(to : Byte) = NumberRange<Byte>(this.int, to.int)
|
||||
@@ -0,0 +1,23 @@
|
||||
package _04_loopy._25_In_the_Loop;
|
||||
|
||||
/**
|
||||
* Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 57). Pearson Education (USA). Kindle Edition.
|
||||
*/
|
||||
public class InTheLoop {
|
||||
public static final int END = Integer.MAX_VALUE;
|
||||
public static final int START = END - 100;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// int count = 0;
|
||||
// for (int i = START; i <= END; i++)
|
||||
// count++;
|
||||
// System.out.println(count);
|
||||
final int end = Integer.MAX_VALUE;
|
||||
int start = end - 100;
|
||||
int count = 0;
|
||||
for (int i = start; i <= end; i++)
|
||||
count++;
|
||||
System.out.println("count = " + count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace `in`.the.loop
|
||||
|
||||
import std.io.*
|
||||
|
||||
val END = Integer.MAX_VALUE
|
||||
val START = END - 100
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
var count = 0
|
||||
// For-loop over integrals always terminates
|
||||
for (i in START..END)
|
||||
count++
|
||||
println(count)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package _04_loopy._31_Ghost_of_Looper;
|
||||
|
||||
public class GhostOfLooper {
|
||||
public static void main(String[] args) {
|
||||
short i = -1;
|
||||
|
||||
while (i != 0)
|
||||
i >>>= 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace ghost.of.looper
|
||||
|
||||
import std.io.*
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
var i : Short = -1.sht
|
||||
while (i != 1.sht)
|
||||
// Lots of magic made explicit:
|
||||
i = (i.int ushr 1).sht
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package _04_loopy._32_Curse_of_Looper;
|
||||
|
||||
public class CurseOfLooper {
|
||||
public static void main(String[] args) {
|
||||
// Place your declarations for i and j here
|
||||
Integer i = 128;
|
||||
Integer j = 128;
|
||||
while (i <= j && j <= i && i != j) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace curse.of.loooper // BUG!!!
|
||||
|
||||
import std.io.*
|
||||
|
||||
class Curse<T : Comparable<T>>() {
|
||||
fun curse(i : T, j : T) {
|
||||
while (i <= j && j <= i && i != j) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
// BUG:
|
||||
// val i : Integer = (128 : Int?) as Integer
|
||||
// val j : Integer = (128 : Int?) as Integer
|
||||
// while (i <= j && j <= i && i != j) {
|
||||
// }
|
||||
Curse<Int>.curse(128, 128)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package _04_loopy._34_Down_for_the_Count;
|
||||
|
||||
public class Count {
|
||||
public static void main(String[] args) {
|
||||
final int START = 2000000000;
|
||||
int count = 0;
|
||||
for (float f = START; f < START + 50; f++)
|
||||
count++;
|
||||
System.out.println(count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace down.`for`.the.count
|
||||
|
||||
import std.io.*
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
// Problematic code does not compile
|
||||
// val START : Int = 2000000000
|
||||
// for (f : Float in START..(START + 50)) {
|
||||
//
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package _05_exceptional._36_Indecision;
|
||||
|
||||
public class Indecisive {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(decision());
|
||||
}
|
||||
|
||||
static boolean decision() {
|
||||
try {
|
||||
return true;
|
||||
} finally {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace indecision
|
||||
|
||||
import std.io.*
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
println(decision())
|
||||
}
|
||||
|
||||
fun decision() : Boolean {
|
||||
try {
|
||||
// Problematic code is illegal, as Java Puzzlers recommend:
|
||||
// return true;
|
||||
} finally {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package _05_exceptional._38_Unwelcome_Guest;
|
||||
|
||||
public class UnwelcomeGuest {
|
||||
public static final long GUEST_USER_ID = -1;
|
||||
|
||||
// private static final long USER_ID;
|
||||
// static {
|
||||
// try {
|
||||
// USER_ID = getUserIdFromEnvironment();
|
||||
// } catch (IdUnavailableException e) {
|
||||
// USER_ID = GUEST_USER_ID;
|
||||
// System.out.println("Logging in as guest");
|
||||
// }
|
||||
// }
|
||||
|
||||
private static long getUserIdFromEnvironment()
|
||||
throws IdUnavailableException {
|
||||
throw new IdUnavailableException(); // Simulate an error
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// System.out.println("User ID: " + USER_ID);
|
||||
}
|
||||
}
|
||||
|
||||
class IdUnavailableException extends Exception {
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace unwelcome.guest
|
||||
|
||||
import std.io.*
|
||||
|
||||
val GUEST_USER_ID = -1
|
||||
val USER_ID =
|
||||
try {
|
||||
getUserIdFromEnvironment()
|
||||
}
|
||||
catch (e : UnsupportedOperationException) {
|
||||
// catch (e : IdUnavailableException) { BUG
|
||||
GUEST_USER_ID
|
||||
}
|
||||
|
||||
fun getUserIdFromEnvironment() = throw UnsupportedOperationException()
|
||||
//fun getUserIdFromEnvironment() = throw IdUnavailableException()
|
||||
|
||||
//class IdUnavailableException() : Ex() {}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
println("User ID: " + USER_ID)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package _05_exceptional._39_The_Reluctant_Constructor;
|
||||
|
||||
public class Reluctant {
|
||||
private Reluctant internalInstance = new Reluctant();
|
||||
|
||||
public Reluctant() throws Exception {
|
||||
throw new Exception("I'm not coming out");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Reluctant b = new Reluctant();
|
||||
System.out.println("Surprise!");
|
||||
} catch (Exception ex) {
|
||||
System.out.println("I told you so");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace the.reluctant.constructor
|
||||
|
||||
import std.io.*
|
||||
|
||||
public class Reluctant() {
|
||||
val internalInstance = Reluctant() // Recursion is obvious
|
||||
{
|
||||
throw Exception("I'm not coming out")
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
try {
|
||||
val b = Reluctant()
|
||||
println("Surprise!")
|
||||
}
|
||||
catch (ex : Exception) {
|
||||
println("I told you so")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package _05_exceptional._42_Thrown_for_a_Loop;
|
||||
|
||||
public class Loop {
|
||||
public static void main(String[] args) {
|
||||
int[][] tests = { { 6, 5, 4, 3, 2, 1 }, { 1, 2 },
|
||||
{ 1, 2, 3 }, { 1, 2, 3, 4 }, { 1 } };
|
||||
int n = 0;
|
||||
|
||||
try {
|
||||
int i = 0;
|
||||
while (true) {
|
||||
if (thirdElementIsThree(tests[i++]))
|
||||
n++;
|
||||
}
|
||||
} catch(ArrayIndexOutOfBoundsException e) {
|
||||
// No more tests to process
|
||||
}
|
||||
System.out.println(n);
|
||||
}
|
||||
|
||||
private static boolean thirdElementIsThree(int[] a) {
|
||||
return a.length >= 3 & a[2] == 3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace thrown.`for`.a.looop // BUG
|
||||
|
||||
import std.io.*
|
||||
import std.*
|
||||
|
||||
fun iarr(vararg a : Int) = a // due to a BUG
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
val tests = array(
|
||||
iarr(6, 5, 4, 3, 2, 1), iarr(1, 2),
|
||||
iarr(1, 2, 3), iarr(1, 2, 3, 4), iarr(1)
|
||||
)
|
||||
|
||||
var n = 0
|
||||
|
||||
try {
|
||||
var i = 0
|
||||
while (true) {
|
||||
if (thirdElementIsThree(tests[i++]))
|
||||
n++
|
||||
}
|
||||
}
|
||||
catch (e : ArrayIndexOutOfBoundsException) {
|
||||
// No more tests to process
|
||||
}
|
||||
println(n)
|
||||
}
|
||||
|
||||
fun thirdElementIsThree(a : IntArray) =
|
||||
// Problematic code does not compile
|
||||
// a.size >= 3 & a[2] == 3
|
||||
a.size >= 3 && a[2] == 3
|
||||
@@ -0,0 +1,34 @@
|
||||
package _06_classy._47_Well_Dog_My_Cats;
|
||||
|
||||
class Counter {
|
||||
private static int count = 0;
|
||||
public static final synchronized void increment() {
|
||||
count++;
|
||||
}
|
||||
public static final synchronized int getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
class Dog extends Counter {
|
||||
public Dog() { }
|
||||
public void woof() { increment(); }
|
||||
}
|
||||
|
||||
class Cat extends Counter {
|
||||
public Cat() { }
|
||||
public void meow() { increment(); }
|
||||
}
|
||||
|
||||
public class Ruckus {
|
||||
public static void main(String[] args) {
|
||||
Dog dogs[] = { new Dog(), new Dog() };
|
||||
for (int i = 0; i < dogs.length; i++)
|
||||
dogs[i].woof();
|
||||
Cat cats[] = { new Cat(), new Cat(), new Cat() };
|
||||
for (int i = 0; i < cats.length; i++)
|
||||
cats[i].meow();
|
||||
System.out.print(Dog.getCount() + " woofs and ");
|
||||
System.out.println(Cat.getCount() + " meows");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
namespace well.dog.my.cats
|
||||
|
||||
import std.io.*
|
||||
import std.*
|
||||
|
||||
open class Counter {
|
||||
class object {
|
||||
private var count = 0
|
||||
fun increment() { count++ }
|
||||
fun getCount() = count
|
||||
}
|
||||
}
|
||||
|
||||
class Dog() : Counter {
|
||||
// Class objects are not inherited:
|
||||
// fun woof() { increment() }
|
||||
fun woof() { Counter.increment() }
|
||||
}
|
||||
|
||||
class Cat() : Counter {
|
||||
// Class objects are not inherited:
|
||||
// fun meow() { increment() }
|
||||
fun meow() { Counter.increment() }
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
val dogs = array(Dog(), Dog())
|
||||
for (dog in dogs)
|
||||
dog.woof()
|
||||
val cats = array(Cat(), Cat())
|
||||
for (cat in cats)
|
||||
cat.meow()
|
||||
// Problematic code does not compile:
|
||||
// println("${Dog.getCount()} woofs")
|
||||
println("${Counter.getCount()} woofs")
|
||||
// println("${Cat.getCount()} meows")
|
||||
println("${Counter.getCount()} meows")
|
||||
}
|
||||
Reference in New Issue
Block a user