I've started working with Arduino and I want to do a time share system so I do not use the delay command.
I have a problem when I try to register objects that inherit from another.
Here I have a test code that should show in the terminal: "Wow wow Miuau miuau ..."
I have doubts when I try to create an Interface and how do I declare the register () function so that Cat and Dog objects can be entered in the Animal type Array.
The following code is only to show the problem:
class Animal {
public:
void message() {
}
};
class Dog : public Animal {
public:
void message() {
Serial.println("Guau guau");
}
};
class Cat : public Animal {
public:
void message() {
Serial.println("Miau miau ");
}
};
class Multiplex {
private:
int index = 0;
Animal objects[5];
public:
void register(Animal object) {
objects[index] = object;
index++;
}
void go() {
for(int i = 0;i<index;i++) {
objects[i].message();
}
}
};
Dog dog;
Cat cat;
Multiplex multiplex;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
multiplex.register(dog);
multiplex.register(cat);
}
void loop() {
// put your main code here, to run repeatedly:
multiplex.go();
delay(1000);
}
Any help is welcome ...
Thanks and sorry for my english.
In this case you have to use polymorphism (virtual methods). But it still won't work with so many copies of "registered" object into the Animal base class (it shows nothing because Animal::message() is called). You have to use pointers (or references - but it's not so easy in this case)
class Animal { // pure virtual class (abstract class)
public:
virtual void message() = 0; // The '= 0;' makes whole class "pure virtual"
};
class Dog : public Animal {
public:
virtual void message() {
Serial.println("Guau guau");
}
};
class Cat : public Animal {
public:
virtual void message() {
Serial.println("Miau miau ");
}
};
class Multiplex {
private:
int index = 0;
Animal * objects[5];
public:
void reg(Animal * object) { // pass pointer to the object
objects[index] = object; // object must be valid for whole time
index++;
}
void go() {
for(int i = 0;i<index;i++) {
objects[i]->message();
}
}
};
Dog dog;
Cat cat;
Multiplex multiplex;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
multiplex.reg(&dog);
multiplex.reg(&cat);
}
void loop() {
// put your main code here, to run repeatedly:
multiplex.go();
delay(1000);
}
If you don't like dynamic polymorphism, you have to use something like object type, switch and typecasting to its correct type.
Related
In Dart we can use generic classes [class]. We can also specialize those classes [class]. However at runtime the specialization is not used. (In C++ this is called template programming)
Example: The following code will result in the output
Hallo world
How are you
class MyClass<T> {
foo( print('Hallo world'); );
}
class MyClassInt implements MyClass<int> {
#override
foo( print('How are you'); );
}
main() {
MyClass<int> a = Myclass<int>();
MyClassInt b = MyClassInt();
a.foo();
b.foo();
}
How can the specialization (here type [int]) be done, that it is called at runtime, i.e.
main() {
MyClass<int> a = Myclass<int>();
a.foo();
}
should result in the outcome "How are you".
As mentioned by jamesdlin, Dart does not support specialization. But you can do something like this to make the illusion:
class MyClass<T> {
factory MyClass() {
if (T == int) {
return MyClassInt() as MyClass<T>;
} else {
return MyClass._();
}
}
// Hidden real constructor for MyClass
MyClass._();
void foo() {
print('Hallo world');
}
}
class MyClassInt implements MyClass<int> {
#override
void foo() {
print('How are you');
}
}
void main() {
final a = MyClass<int>();
final b = MyClassInt();
final c = MyClass<String>();
a.foo(); // How are you
b.foo(); // How are you
c.foo(); // Hallo world
}
I want to understand why Dart can see that the object b in printBye() function knows it is an Instance of Bye, but it does not know how to figure out the instance variable a;
class Hello {
void world<T>(T a) {}
}
class Bye {
int a = 1;
}
class Something extends Hello {
#override
void world<T>(T a) {
printBye(a);
}
}
void printBye<T>(T b) {
print(b); // prints Instance of Bye
print(b.a); // error
}
void main() {
new Something()..world(new Bye());
}
https://dartpad.dartlang.org/527e6692846bc018f929db7aea1af583
Edit: here's a simplified version of the code that achieves the same effect:
class Bye {
int a = 1;
}
void printBye<T>(T b) {
print(b); // prints Instance of Bye
print(b.a); // error
}
void main() {
printBye(new Bye());
}
Here's a simple way to look at it: you did call printBye with a Bye, but you could have called it with any other type. When you call printBye with an int, that int wont have a .a. Therefore, you have to assume that printBye could be called with anything. Object represents that anything as every class derives from it.
If you are sure that it will be called with a Bye or a subclass, you can do this to get rid of the error:
class Bye {
int a = 1;
}
void printBye<T extends Bye>(T b) {
print(b); // prints Instance of Bye
print(b.a); // not an error anymore
}
void main() {
printBye(new Bye());
}
More info: https://dart.dev/guides/language/language-tour#restricting-the-parameterized-type
I want to create a new object of given type inside of generic in Vala language.
class MyClass <T> : GLib.Object
{
protected T data;
public MyClass ()
{
data = new T ();
}
}
I understand that this can't work, but what is the way to do something like that?
You are probably best instantiating it when calling the constructor for MyClass:
void main () {
new MyClass<Test> (new Test ());
new MyClass<Example> (new Example ());
}
class MyClass <T>
{
protected T data;
public MyClass (T data)
{
this.data = data;
}
}
class Test {}
class Example {}
Vala generics do not currently provide constraints. If you are going to pass in a dependency in this way you may want to consider using an interface type instead of a generic type.
Update
If you are wanting to implement a factory then an interface with a static method or function is probably best:
void main () {
var a = CommandFactory.get_command ("A");
var b = CommandFactory.get_command ("B");
a.run ();
b.run ();
}
namespace CommandFactory {
Command get_command (string criteria) {
Command result = null;
switch (criteria) {
case "A":
result = new CommandA ();
break;
case "B":
result = new CommandB ();
break;
default:
assert_not_reached ();
}
return result;
}
}
interface Command:Object {
public abstract void run ();
}
class CommandA:Object, Command {
void run () { print ("A\n"); }
}
class CommandB:Object, Command {
void run () { print ("B\n"); }
}
I assume by 'abstract fabric pattern' you mean 'abstract factory pattern'? You could try using GType introspection to then instantiate the Object, but it must be a GObject and you by pass Vala's static analysis checks:
void main () {
new MyClass<Example> (new Example ());
/* These will fail at runtime
new MyClass<string> ("this will fail at runtime");
new MyClass<ThisWillFailAtRuntime> (new ThisWillFailAtRuntime ());
*/
}
class MyClass <T>
{
protected T data;
public MyClass (T data)
{
assert (typeof(T).is_object());
this.data = Object.new (typeof(T));
}
}
class Example:Object {}
class ThisWillFailAtRuntime {}
Note that Object.new() is also a static method.
I'm not sure what you are trying to achieve, but you are probably better looking more closely at interfaces and favouring composition over inheritance in your object data model.
Is there way to overriding method in Dart like JAVA, for example:
public class A {
public void handleLoad() {
}
}
And when overriding:
A a = new A() {
#Override
public void handleLoad() {
// do some code
}
};
No, Dart does not have anonymous classes. You have to create a class that extends A and instantiate it.
No but it much less useful in Dart because you can just reassign function:
typedef void PrintMsg(msg);
class Printer {
PrintMsg foo = (m) => print(m);
}
main() {
Printer p = new Printer()
..foo('Hello') // Hello
..foo = ((String msg) => print(msg.toUpperCase()))
..foo('Hello'); //HELLO
}
However you will need some extra boilerplate to access instance.
Use type Function:
class A {
final Function h
A(this.h);
void handleLoad(String loadResult) { h(loadResult); }
}
Or
class A {
final Function handleLoad;
A(this.handleLoad);
}
A a = new A((String loadResult){
//do smth.
});
MyStack()
{
Vector<Integer> v=new Vector<Integer>(10,2);
}
void push(int n)
{
v.addElement(n);
}
void pop()
{
if(v.isEmpty())
System.out.println("Stack underflow!");
else
System.out.println(v.elementAt(0));
}
void display()
{
for(int i=0;i<v.size();i++)
System.out.print(v.elementAt(i) +" ");
}
}
class StackDemo
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
MyStack s=new MyStack();
int option=0;
do
{
System.out.println("1: Push\n2:Pop\n3:Display\n4:Quit");
System.out.println("Enter your option: ");
option=in.nextInt();
switch(option)
{
case 1:
{
System.out.println("Enter an integer:");
int n=in.nextInt();
s.push(n);break;
}
case 2:s.pop();break;
case 3:s.display();break;
}
}
while(option!=4);
}
}
// throws an error: variable v not found. Any help would be much appreciated.Thanks.
It looks like v is being created locally in your constructor instead of as a member of your class.
Try defining v as a class member and then simply assign it in your constructor.
class MyStack {
Vector<Integer> v;
public MyStack() {
v = new Vector<Integer>(10,2);
}
}
Or just assign it when you define it:
class MyStack {
Vector<Integer> v = new Vector<Integer>(10,2);
}
Check out the Java tutorial on class members.