Differences between a class with static members and a namespace/module in typescript - typescript2.0

There are a lot of discussions about how and when to use static classes and how to achieve a real static class in typescript. But I have not found any explanation about the differences between a class with only static members paired with an unuseable constructor and a namespace/module.
How do them both affect the global namespace and what is the difference for the memory and usage?
Because in my opinion and what the official documentation says, it would be more easy to achieve the functionality of a static class by using a namespace construct. It is less code and more easy then to use a real class.

You can always look at the compiled javascript output to see the difference. A namespace is an object that will be merged with other namespaces with the same name.
namespace A{
export function b(){
}
}
javascript output:
var A;
(function (A) {
function b() {
}
A.b = b;
})(A || (A = {}));
A class is a function and a static member is a property of the function.
class A{
public static b(){
}
}
javascript output:
var A = /** #class */ (function () {
function A() {
}
A.b = function () {
};
return A;
}());
Both, namespace and class, will occupy the same name "A" in the global namespace. From the perspecive of a client, there is no difference in accessing a static class member or a function inside a namespace:
A.b();
Personally, I don't use static class members or namespaces, i always define functions and variables at the top level inside a module, and use different modules to group different functions.
The typescript homepage has a good topic about this: https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html

Related

create nested class (kt) for existing class (java), extensions

does Kotlin compiler allow extending classes with inner and/or nested classes and if so what's the correct syntax?
in EnclosingClass.java
class EnclosingJavaClass {
class NestedJavaClass1 {}
class NestedJavaClass2 {}
// ...
}
this is what i'm unsure of below,
in EnclosingClassExtensions.kt
class EnclosingJavaClass.NestedKotlinClass {
// ...
}
assuming that EnclosingClass.java cannot be modified (eg: library code), can i declare somehow a EnclosingClass.SomeNewKotlinClass ?

Kotlin: Difference between constant in companion object and top level

The general pattern to create constants in Kotlin seems to be using companion objects. However, I can also define a constant at the file level. Why is that not so popular? Am I missing something?
With companion object:
class Example {
companion object {
const val CONSTANT = "something"
}
On top level:
const val CONSTANT = "something"
class Example {
}
In Java you're forced to put all static field and method declarations in a class and often you even have to create a class just for that purpose. Coming to Kotlin, many users look for the equivalent facility out of habit and end up overusing companion objects.
Kotlin completely decouples the notions of a file and a class. You can declare any number of public classes in the same file. You can also declare private top-level functions and variables and they'll be accessible only to the classes within the same file. This is a great way to organize closely associated code and data.
Compared to top-level declarations, the syntax of companion objects is quite unwieldy. You should use them only when you specifically want to associate some public static code or data with a class and want your users to qualify access to it with the class's name. The use cases for this are quite rare and in most cases the top-level declarations are more natural.
Whenever you have some private static code/data that you want to couple to a class, you'll be better served with private top-level declarations.
Finally, sometimes the concern of the generated bytecode matters. If, for whatever reason, you have to produce a Java class with Kotlin code such that the class has a static member, you must resort to a companion object and a special annotation.
Differences in usage
Defining the field in a companion object limits the scope it is available in without importing to only that class, which can help keeping the data from being used in unexpected places.
Defining in the file makes the field available to any code in the same package as the field.
Differences in Bytecode
const val CONSTANT = "something"
class Example {
}
Creates the following:
Example.java
public final class Example {}
XKt.java
import kotlin.Metadata;
import org.jetbrains.annotations.NotNull;
public final class XKt {
public static final String CONSTANT = "something";
}
Whereas:
class Example {
companion object {
const val CONSTANT = "something"
}
}
Creates the following:
public final class Example {
public static final String CONSTANT = "something";
public static final Example.Companion Companion = new Example.Companion((DefaultConstructorMarker) null);
public static final class Companion {
private Companion() {}
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
I think that basically depends on whether you want that constant to be part of a class. If you put it inside a companion object, it will be accessed like this:
Example.CONSTANT
If you choose to put a constant on file level, it will be imported from other files and accessed with simply CONSTANT normally.
There are reasons for putting constants in classes as well as for putting them top-level.
Note that the const keyword can only be applied to variables of type String or primitive types (Int etc.) (reference). For most cases though, there's no need to apply the keyword. Defining constant values as shown in the following works as well:
val constantFIS = FileInputStream("path")
Sometimes you actually need to put constant outside of companion object. Apparently constants in companion objects are not that “that much” constant as one would suppose. For instance:
internal const val MY_FOO = "It's my ${Foo.FOO}";
open class Foo {
internal companion object {
const val FOO = "foo";
}
}
#Kaboom(name=MY_FOO)
open class Bar {}
Above code is not compiling. As long some “constans” are part of companion objects, they're not really constants. But when you move FOO outside of companion object, everything works.
On the other hand I'd like the compiler to do the work for me and to find out if it is possible to functionally turn some static final field to a constant or not. Why should I put my effort and time to decide what is or is not a literal constant for the compiler? It is just wrong.

What's the purpose of allowing the declaration of an abstract method in a non-abstract class?

According to this article, it's possible, in Dart, to define a non-abstract class to have an abstract (or not-implemented) method. The abstract method causes a warning, but does not prevent instantiation.
What's the purpose of allowing the declaration of an abstract method in a non-abstract (or concrete) class in Dart? Why was Dart designed to work in this way?
The specification is actually very explicit about declaring abstract methods in a concrete class:
It is a static warning if an abstract member m is declared or inherited in a concrete class
We wish to warn if one declares a concrete class with abstract members.
It is a static warning if a concrete class has an abstract member (declared or inherited).
They don't have any intended purpose for it, which is why they issue warnings. If you're familiar with Java: it's similar to accessing a static member via an object, which is also pointless and triggers a warning.
As for why it passes compilation, Dart uses an optional type system, which means typing concepts should not affect the semantics of the language, and that's simply what Dart is enforcing:
The purpose of an abstract method is to provide a declaration for purposes such as type checking and reflection.
The static checker will report some violations of the type rules, but such violations do not abort compilation or preclude execution.
An abstract method in a concrete class allows you to provide the type signature for a method that is implemented via noSuchMethod() instead. Providing a noSuchMethod() implementation will also silence the warning.
In strong mode, simply having an abstract method in a concrete class will result in an error, unless the class also implements the noSuchMethod() interface.
In short, the purpose of abstract methods in a concrete class is to provide type signatures for noSuchMethod() implementations. This avoids warnings for calling an unknown method and in strong mode (which is the default for dartdevc, and will be first the default and then mandatory for Dart 2.0) these type signatures are necessary for code with noSuchMethod() to even compile, unless the target is of type dynamic.
Example:
class A {
void f();
dynamic noSuchMethod(Invocation inv) => null;
}
void main() {
var a = new A();
a.f();
}
If we replace a.f() with (say) a.f(0), then this will result in an error (in strong mode) for having called the method with the wrong number of parameters. If we omit the void f() declaration, then we'll get an error that A does not have a method f(). If we omit the noSuchMethod() implementation, then the complaint will be that f() lacks a method body, even though A isn't abstract.
The following code provides a more realistic example:
import "dart:mirrors";
class DebugList<T> implements List<T> {
List<T> _delegate;
InstanceMirror _mirror;
DebugList(this._delegate) {
_mirror = reflect(_delegate);
}
dynamic noSuchMethod(Invocation inv) {
print("entering ${inv.memberName}");
var result = _mirror.delegate(inv);
print("leaving ${inv.memberName}");
return result;
}
}
void main() {
List<int> list = new DebugList<int>([1, 2, 3]);
int len = list.length;
for (int i = 0; i < len; i++) print(list[i]);
}
This example creates a debugging decorator for List<T>, showing all method invocations. We use implements List<T> to pull in the entire list interface, inheriting dozens of abstract methods. This would normally result in warnings (or in strong mode, errors) when run through dartanalyzer, as we're missing implementations for all these methods normally provided by List<T>. Providing a noSuchMethod() implementation silences these warnings/errors.
While we could also manually wrap all 50+ methods, this would be a lot of typing. The above approach also will continue to work if new methods are added to the list interface without us having to change our code.
Use cases for explicitly listing methods in a concrete class are less common, but can also occur. An example would be the addition of getters or setters to such a debugging decorator that allows us to inspect or set instance variables of the delegate. We will need to add them to the interface, anyway, to avoid warnings and errors from using them; the noSuchMethod() implementation can then implement them using getField() and setField(). Here's a variant of the previous example, using stacks instead of lists:
// main.dart
import "dart:mirrors";
import "stack.dart";
class DebugStack<T> implements Stack<T> {
Stack<T> _delegate;
InstanceMirror _mirror;
DebugStack(this._delegate) {
_mirror = reflect(_delegate);
}
dynamic _get(Symbol sym) {
// some magic so that we can retrieve private fields
var name = MirrorSystem.getName(sym);
var sym2 = MirrorSystem.getSymbol(name, _mirror.type.owner);
return _mirror.getField(sym2).reflectee;
}
List<T> get _data;
dynamic noSuchMethod(Invocation inv) {
dynamic result;
print("entering ${inv.memberName}");
if (inv.isGetter)
result = _get(inv.memberName);
else
result = _mirror.delegate(inv);
print("leaving ${inv.memberName}");
return result;
}
}
void main() {
var stack = new DebugStack<int>(new Stack<int>.from([1, 2, 3]));
print(stack._data);
while (!stack.isEmpty) {
print(stack.pop());
}
}
// stack.dart
class Stack<T> {
List<T> _data = [];
Stack.empty();
Stack.from(Iterable<T> src) {
_data.addAll(src);
}
void push(T item) => _data.add(item);
T pop() => _data.removeLast();
bool get isEmpty => _data.length == 0;
}
Note that the abstract declaration of the _data getter is crucial for type checking. If we were to remove it, we'd get a warning even without strong mode, and in strong mode (say, with dartdevc or dartanalyzer --strong), it will fail:
$ dartdevc -o main.js main.dart
[error] The getter '_data' isn't defined for the class 'DebugStack<int>' (main.dart, line 36, col 15)
Please fix all errors before compiling (warnings are okay).

Describing a function parameter that takes a class as an argument in TypeScript

I want to write a function where you parse the class type (the class, not an instance) then the function will instantiate an instance based on that parameter.
This is best explained by example:
//All possible paramter types must inherit from this base class
class Base { public name : string = ''; }
//These are possible classes that could be parsed to the function
class Foo extends Base { constructor() { super(); console.log("Foo instance created"); } }
class Bar extends Base { constructor() { super(); console.log("Bar instance created"); } }
//This function should take a class that inherits from 'Base' as a paramter - then it will create an instance
function Example(param : ?????????) : Base //I don't know what type the 'param' should be
{
return new param(); //Create instance?? How do I do this
}
//This should be the output - if it worked (but it doesn't)
Example(Foo); //Logs "Foo instance created""
Example(Bar); //Logs "Foo instance created""
//So if this worked, it would become possible to do this:
let b : Foo = Example(Foo);
let c : Bar = Example(Bar);
So my questions is: what type would the param for the 'Example' function be? And how would I create an instance of param from within the function.
Note, if this question is a duplicate I apologise - but I don't know the technical name for this process so it is difficult to research.
You want something like this.
function Example<T extends Base>(param: new () => T): T {
return new param();
}
We know that you'll have some type that is a Base. We're going to name it T, and we'll say that T extends Base to enforce that.
We also know that param will construct a T with no parameters. We can write new () => T to describe that.
Basically the way to think about this is that a class has both an instance side and a static side (also called the "constructor" side). In your example, Base, Foo, and Bar on their own have the static side.
The static side for each of them consists of all the static members you specify (and there aren't any in this case), along with the construct signature. In your case, Example takes a constructor expects no arguments, and produces some subtype of Base.

Why do I get a compilation error when calling println method in the class body? #Java

class Test {
int a = 100;
System.out.println(a);
}
class Demo {
public static void main(String args[]) {
Test t = new Test();
}
}
I'm new to programming. I found this code when I'm practicing. I don't understand why I'm getting this error.
Here is the error I'm getting.
Demo.java:3: error: <identifier> expected
System.out.println(a);
^
Demo.java:3: error: <identifier> expected
System.out.println(a);
^
2 errors
Compilation failed.
Can you guys explain why I'm getting this error?
You can't call a method directly from the java class body.
Create a constructor in your Test class, and put the print in it :
class Test {
int a = 100;
public Test() {
System.out.println(a);
}
}
Note that if for some reason you really want a statement to be executed when the class is loaded without using a constructor, you can define a static block, here an example :
class Test {
static int a = 100;
static {
System.out.println(a);
}
}
However, this is just for reference and really not needed in your case.
From Declaring Classes in the Java tutorial:
In general, class declarations can include these components, in order:
Modifiers such as public, private, and a number of others that you will encounter later.
The class name, with the initial letter capitalized by convention.
The name of the class's parent (superclass), if any, preceded by the keyword extends. A class can only extend (subclass) one parent.
A comma-separated list of interfaces implemented by the class, if any, preceded by the keyword implements. A class can implement more than one interface.
The class body, surrounded by braces, {}.
You can't make any function calls outside of a method declaration.