Coffeescript code:
class Animal
constructor: (#name) ->
move: (meters) ->
alert #name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
alert Snake instanceof Animal
Here is a link.
I really think this result true.
And my reason is this __extends method in compiled JavaScript:
__extends = function (child, parent) {
for(var key in parent) {
if(__hasProp.call(parent, key)) child[key] = parent[key];
}function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
};
child.prototype.prototype is parent.
Can someone tell me why?
And I know below is true:
alert new Snake('a') instanceof Animal
Your Snake is a subclass of Animal:
class Snake extends Animal
That means that Snake (a "class") is actually an instance of Function, not Animal. A Snake object, on the other hand, would be an instance of Animal:
alert Snake instanceof Function # true
alert (new Snake) instanceof Animal # true
And if you try to get a Snake instance to move:
(new Snake('Pancakes')).move()
you'll see that the right methods are called.
Demo: http://jsfiddle.net/ambiguous/3NmCZ/1/
Related
class Car {
var name;
var model;
var cc;
Car(this.name, this.model, this.cc);
printAll() {
print(name);
print(model);
print(cc);
}
print(name); //Showing Error
}
void main() {
var obj = Car("Marcedes", "Class E", 5000);
obj.printAll();
}
Why i can't do any kind of operation outside the method body. The code generates error in compilation which given bellow. The code write in Dartpad.
Error in Compilation. The output show
Error compiling to JavaScript:
main.dart:1:7:
Error: The non-abstract class 'Car' is missing implementations for these members:
You have declared a method named print with a parameter called name but without a method body, i.e. an abstract method. In order to instantiate a class, Dart obviously has to know what the method body is, therefore you cannot instantiate an abstract class.
You need to do two things:
Because you have an abstract method, and abstract methods are only allowed in abstract classes, you need to mark Car as abstract.
You need to create a subclass of Car that overrides print with an implementation, and then instead instantiate that class.
Something like this:
abstract class Car {
var name;
var model;
var cc;
Car(this.name, this.model, this.cc);
printAll() {
print(name);
print(model);
print(cc);
}
print(name); // Abstract method `print` with no implementation
}
class ConcreteCar extends Car {
ConcreteCar(name, model, cc): super(name, model, cc);
#override
print(name) {
// Implementation of `print`
}
}
void main() {
var obj = ConcreteCar("Mercedes", "Class E", 5000);
obj.printAll();
}
Note: I left the implementation of print empty because I didn't understand the reason for the abstract print method and what the goal of the design is. But it should be trivial for you to fill out the missing pieces.
I am trying Libgdx Game Class to make a game.And I am following a book.There is an example. Example has 4 classes and 1 DesktopLauncher. DesktopLauncher use StarfishCollector3() class to main function. Despite I dont call create method and render method which are in GameBeta abstract class to StarfishCollector3, the project is working.Can you explain what I dont know.
class StarfishCollector3 : GameBeta() {
var turtle:Turtle=null
var starfish:ActorBeta=null
var ocean:ActorBeta=null
var winMessage:ActorBeta=null
var win:Boolean = true
override fun initialize() {
ocean= ActorBeta()
ocean.setTexture(Texture( Gdx.files.internal("water.jpg") ))
mainStage.addActor(ocean)
starfish = ActorBeta();
starfish.setTexture(Texture(Gdx.files.internal("starfish.png")) );
starfish.setPosition( 380F,380F );
mainStage.addActor( starfish );
turtle = Turtle()
turtle.setTexture( Texture(Gdx.files.internal("turtle-1.png")) )
turtle.setPosition( 20F,20F )
mainStage.addActor( turtle )
winMessage = ActorBeta();
winMessage.setTexture( Texture(Gdx.files.internal("you-win.png")) );
winMessage.setPosition( 180F,180F );
winMessage.setVisible( false );
mainStage.addActor( winMessage );
win = false }
override fun update(dt: Float) {
if (turtle.overlaps(starfish as ActorBeta)){
starfish.remove()
winMessage.setVisible(true)} }
}
abstract class GameBeta: Game() {
protected var mainStage: Stage=null
abstract fun initialize()
override fun create() {`
mainStage = Stage()
initialize() }
abstract fun update(dt:Float)
.
override fun render() {
var dt= Gdx.graphics.getDeltaTime()
mainStage.act()
update(dt)
Gdx.gl.glClearColor(0F,0F,0F,1F)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
mainStage.draw()
}
}
The heirarchy of StarfishCollector3 is that it extends GameBeta, which extends Game, which implements ApplicationListener.
In DesktopLauncher you instantiate a StarfishCollector3 and pass it as an implicit ApplicationListener to an Application constructor by calling something like new LwjglApplication(starfishCollectior, config);. When you instantiate that LwjglApplication (or Lwjgl3Application or AndroidApplication, etc. depending on backend), the constructor of that Application class sets up the game engine. It creates all the classes for managing OpenGL and drawing the game in a repeating loop, pausing and resuming, etc.
So the Application class is using your StarfishCollector3 as an ApplicationListener and calling its relevant lifecycle methods at the appropriate times.
I want to access a member of the MainFragment class from PersonAdapter class but none of them are available. I tried making both the classes and the members public and private also but so far nothing worked.
I guess I'm missing something obvious but I just can't figure it out.
class MainFragment : Fragment() {
lateinit var personAdapter: PersonAdapter
lateinit var personListener: OnPersonSelected
private var realm: Realm by Delegates.notNull()
lateinit var realmListener: RealmChangeListener<Realm>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.fragment_main, container, false)
return v
}
class PersonAdapter() : RecyclerView.Adapter<ViewHolder>() {
var localPersonList = personList
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindItems(localPersonList[position])
holder.itemView.setOnClickListener {
Toast.makeText(context, "click", Toast.LENGTH_SHORT).show()
//I want to reach personListener from here
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent!!.context).inflate(R.layout.person_list_item, parent, false)
return ViewHolder(v)
}
}}
In Kotlin, nested classes cannot access the outer class instance by default, just like nested static classes can't in Java.
To do that, add the inner modifier to the nested class:
class MainFragment : Fragment() {
// ...
inner class PersonAdapter() : RecyclerView.Adapter<ViewHolder>() {
// ...
}
}
Note that an inner class holds a reference to its containing class instance, which may affect the lifetime of the latter and potentially lead to a memory leak if the inner class instance is stored globally.
See: Nested classes in the language reference
In Kotlin, there are 2 types of the nested classes.
Nested Class
inner Class
Nested class are not allowed to access the member of the outer class.
If you want to access the member of outer class in the nested class then you need to define that nested class as inner class.
class OuterClass{
var name="john"
inner class InnerClass{
//....
}
}
Add inner
Note that Android Studio's Code completion(IntelliSense) doesn't work right inside the inner class
class OuterClass {
val outerVariable = "Hello, World!"
inner class InnerClass {
// Code completion doesn't work here
val innerVariable = outerVariable // Code completion work
fun innerFunction() {
// Code completion work
}
}
}
I have an abstract class Model with a static attribute and another generic class Controller<T extends Model>. I want to access the static attribute of Model in an instance of Controller. That should like this:
abstract class Model{
static hasStatus: boolean = false;
}
class MyModel extends Model{
static hasStatus = true;
}
class Controller<T extends Model>{
constructor(){
if(T.hasStatus)...
}
}
But TS says 'T' only refers to a type, but is being used as a value here.
Is there an easy way to achieve this? Or should i subclass Controller for each Heritage of Model and implement a method to retrieve the value?
There is no way to do that in typescript. Generic type parameters can only appear where types may appear in declarations, they are not accessible at runtime. The reason for that is simple - single javascript function is generated for each method of the generic class, and there is no way for that function to know which actual type was passed as generic type parameter.
If you need that information at runtime, you have to add a parameter to the constructor and pass a type yourself when calling it:
class Controller<T extends Model>{
constructor(cls: typeof Model){
if (cls.hasStatus) {
}
}
}
let c = new Controller<MyModel>(MyModel);
Here is how it looks when compiled to javascript to illustrate the point - there is nothing left of generic parameters there, and if you remove cls parameter there is no information about where hasStatus should come from.
var Controller = (function () {
function Controller(cls) {
if (cls.hasStatus) {
}
}
return Controller;
}());
var c = new Controller(MyModel);
What i would like to do, is create TreeViewer using databinding for a POJO class, which has multiple list properties, and all of them needs to be observed, and displayed in the viewer.
I would like to display a tree like:
Person
\
|- Dog // dogs list
|- Dog
|- Cat // cats list
|- Cat
|- Cat
Example:
public class Cat {
// ...
}
public class Dog {
// ...
}
The class which has a list reference with both types:
public class Person {
private List<Dog> dogs = Lists.newArrayList();
private List<Cat> cats = Lists.newArrayList();
// getters and setters which fire property change listeners.
}
And then i create the TreeViewer, and set the content provider:
treeViewer = new TreeViewer(parent);
IObservableFactory observableFactory = new IObservableFactory() {
public IObservable createObservable(final Object target) {
// target is a Person. What should I return here?
// If I return for example the observed dogs, cats wont be bound:
return BeanProperties.list("dogs").observe(target);
}
};
IContentProvider provider = new ObservableListTreeContentProvider(observableFactory, null);
treeViewer.setContentProvider(provider);
But because the factory can only return one IObservable, I can't observe both cats and dogs. How could i do that?
With your initial design, you can't do it. Why are dogs and cats on the same level in the tree? Levels usually contain same objects (because why would you put your cousins under your parents?).
OK, cats and dogs are both Animals, but then make them extending Animal class and use something like this:
class Person {
List<Animal> pets; // both dog and cats
}
IObservableFactory observableFactory = new IObservableFactory() {
public IObservable createObservable(final Object target) {
return BeanProperties.list("pets").observe(target);
}
};
And even this would not be a good idea, in case you want to display properties which are only related to cats, dogs, rabbits... .
I am not sure, why you want to use observable content provider (as usually Tree is convenient way to just display something). Wouldn't it be enough for you to use ITreeContentProvider? In this case you could stick with you model of having separate dogs and cats collections and do something like this:
class PetsContentProvider immplements ITreeContentProvider {
public boolean hasChildren(Object element) {
if (element instanceof Person) {
Person person = (Person) element;
return person.getCats().size > 0 || person.getDogs().size() > 0;
}
return false;
}
public Object getParent(Object element) {
// TODO: still better to have a common class
if((element instanceof Dog) || (element instanceof Cat)) {
// cast to dog or cat (or better animal)
// Animal pet = (Animal) element;
return pet.getOwner();
}
return null;
}
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof Person) {
Person person = (Person) parentElement;
return person.getCats().toArray(); // and dogs
}
return EMPTY_ARRAY;
}
}
For more information, please see this very good article on JFace Trees.
And just traditionally Vogella's article on JFaceData Binding.