I am trying abstract classes I found one issue that I have to implement the non-abstract method having a body in child classes
code:
abstract class Animal{
void breathe(); //abstract method
void makeNoise(){
//non abstract method
print('making animal noises!');
}
}
abstract class IsFunny{
void makePeopleLaugh();//abstract method
}
class TVShow implements IsFunny{
String name;
#override
void makePeopleLaugh() {
// TODO: implement makePeopleLaugh
print("TV show is funny and make people laugh");
}
}
class Comedian extends Person implements IsFunny{
Comedian(String name, String nation) : super(name, nation);
#override
void makePeopleLaugh() {
// TODO: implement makePeopleLaugh
print('make people laugh');
}
}
class Person implements Animal{
String name,nation;
Person(this.name,this.nation);
//we must implement all the methods present in Abstract class and child should override the abstract methods
#override
void breathe() {
// TODO: implement breathe
print('person breathing through nostrils!');
}
//there should be no compulsion to override non abstract method
#override
void makeNoise() {
// TODO: implement makeNoise
print('shouting!');
}
}
void main(List arguments) {
var swapnil=new Person('swapnil','India');
swapnil.makeNoise();
swapnil.breathe();
print('${swapnil.name},${swapnil.nation}');
}
here I am trying not to implement makeNoise method in my Person class but it gives error and says abstract method must be implemented.
Is this bug or I am getting concept wrong
You are using implements, which is used for interfaces, not for inheritance. The keyword you are looking for is extends.
abstract class Foo {
void doThing() {
print("I did a thing");
}
void doAnotherThing();
}
class Bar extends Foo {
#override
void doAnotherThing() {
print("I did another thing");
}
}
I don't believe this is a bug. The method is still in an abstract class that you are implementing. I think that you instead intended to extend the class in which case you would call super.makeNoise() in the override.
I figured out the solution after some time I understood that when inheriting abstract class I should have used extends keyword instead of implements due to which dart was telling me to also implement the non-abstract method as it is compulsory to implement all methods when using interfaces.
I think my question was silly
Related
I am writing a payment service class in Dart that wraps more than 1 payment provider. The expectation is the caller can simply switch one to another without any hassle.
Let's imagine I have classes like this:
enum PaymentProvider { providerA, providerB }
abstract class PaymentService {
void processPayment(Order oder);
}
class PaymentServiceA implements PaymentService {
final String appKey;
final String merchantId;
PaymentServiceA(this.appKey, this.merchantId);
#override
void processPayment(Order oder) {
// concrete implementation to process payment
}
String getVoucher() {
// return voucher code
}
}
class PaymentServiceB implements PaymentService {
final PaymentBOptions options;
PaymentServiceB(this.options);
#override
void processPayment(Order oder) {
// concrete implementation to process payment
}
List<PaymentBHistory> getPaymentHistory() {
// return payment history
}
}
class PaymentBOptions {
final bool sendEmailReceipt;
final Function()? successCallback;
PaymentBOptions(this.sendEmailReceipt, this.successCallback);
}
So here PaymentServiceA and PaymentServiceB have same method (processPayment) so we can create base class PaymentService and let them implements this base class.
However as you can see each of them also has different constructor parameter and specific methods.
How is the best approach to create PaymentService that wrap more than 1 provider like this?
I was trying to use factory pattern like this:
abstract class PaymentService {
factory PaymentService(PaymentProvider provider) {
switch(provider) {
case PaymentProvider.providerA:
String appKey = "xxxx";
String merchantId = "123"
return PaymentServiceA(appKey, merchantId);
case PaymentProvider.providerB:
PaymentBOptions options = PaymentBOptions(() {
});
return PaymentServiceB(options);
}
}
void processPayment(Order order);
}
But I don't think this is the good practice because:
If we create PaymentServiceA or PaymentServiceB instance using PaymentService factory method it will return as PaymentService and we need to cast to appropriate class in order to access specific PaymentService method.
We can't supply specific constructor parameter of PaymentServiceA or PaymentServiceB outside PaymentService abstract class via factory constructor.
Any idea on how is the best practice and what's the suitable design pattern when facing this kind of scenario?
Thanks.
class Student {
static void getDetails() {
print('Get details method of Student class');
}
}
class DartStudent extends Student {
static void getDetails() {
print('Get details method of DartStudent class');
}
}
void main() {
DartStudent.getDetails();
}
Output : Get details method of DartStudent class
Expected : Error. static method cannot be overriden.. or something wrong..
what's wrong with me?
getDetails() in DartStudent class is not overriding parent class's method?
You can't override static methods.
The two static methods you declared there are in fact two different static methods, not the same, overriden one.
Answer for a different question, but related:
Dart doesn't inherit static methods to derived classes. So it makes no sense to create abstract static methods (without implementation).
Also check out Why shouldn't static methods be able to be overrideable?. It provides a thorough explanation of why static methods should not be overrideable in general.
Is it possible to call a second ancestor method in dart? something like super.super.hello()? If it's possible, how can it be written?
class A {
void hello() {
print('A');
}
}
class B extends A {
#override
void hello() {
print('B');
}
}
class C extends B {
#override
void hello() {
// How to call the hello() implemented in the class A here?
}
}
void main() {
var c = C();
c.hello();
}
It's not possible.
The reason it's not possible is that it breaks abstraction.
When you look at class C extend B, all you need to know about B is which signatures its members has and which interfaces it implements. As long as that stays effectively the same, your valid code will keep working.
Consider what would happen if the author of B decided to make themselves a helper base-class:
abstract class _BaseB extends A {
String get _myName;
#override
void hello() {
print(_myName);
}
}
class B extends _BaseB {
#override
String get _myName => "B";
}
That's a perfectly valid refactoring. The resulting class B has all the same members and implements all the same interfaces (and also _BaseB, but it's private so nobody can see that).
The C class above would keep working if all it does is to call super.hello(). If it had a way to ask for super.super.hello(), that might no longer be valid.
Similarly if the B class was changed to:
class B implements A {
#override
void hello() {
print("B");
}
}
(changing extends to implements), then all methods of B works the same as before and it implements the same interfaces. Again, there is no visible differences to the users of the B class.
But if you could call something like A.super.hello() to reach the A class's hello method, then that would now break because that method isn't in the B class at all.
So, by restricting super.hello() to only call methods on the precise class you write as the superclass, you are prevented from introducing dependencies on the implementation of B, dependencies which would make otherwise valid refactorings into breaking changes.
How can I have an abstract private method in dart?
// person.dart
abstract class Person{
void _walk(); //Abstract Method
void _talk(); //Abstract Method
}
// jay.dart
import "person.dart";
class Jay extends Person{
#override
void _walk() {
print("Jay can walk");
}
#override
void _talk() {
print("Jay can talk");
}
}
I want to hide _walk and _talk from Jay instance
package:meta provides a #visibleForOverriding annotation that might do what you want. Note that violating it will generate only an analysis warning, and it won't be enforced at runtime.
Personally I think that putting things that are meant to be private in the abstract base class is a bad idea since they shouldn't be part of the interface. Consider instead doing:
abstract class Person {
...
}
abstract class _Person extends Person {
void walk();
void talk();
}
and now your library can internally derive classes from _Person and use walk and talk, and they won't be exposed at all to external consumers of your library.
I have some class like this:
abstract class Parent {
void doSomething({dynamic number});
}
class Child01 extends Parent {
#override
void doSomething({dynamic number}) {
...
}
}
class Child02 extends Parent {
#override
void doSomething() {
...
}
}
How can I override doSomething() method in class Child02 without an optional parameter, like above?
You cannot do that and the reason can be seen in the following code:
List<Parent> list = [Child01(), Child02()];
list.forEach((e) => e.doSomething(number: 5));
This is allowed since Parent tells us there is an optional parameter to doSomething called number. But what happens when we end up calling a Child02 object with this parameter it does not expect? You are not allowed in Dart to send arbitrary arguments (named or not) to a method and see if it is going to be used or not.