简体   繁体   中英

Why field declaration is must in class as it implements an interface

I want to clear my concept in implementation of an interface on a class.

An interface is something like a template which cannot make an impact until a class implements it. (link)

So if I define an interface as:

interface IVehicle {
    color: string,
    model_no: number,
}

And then I make a class as:

class Vehicle implements IVehicle {

}

It's giving me red underline at class name. Why I must declare the fields again in the class as it is implementing an interface it must not fetch its fields?

Why we must write like this?

class Vehicle implements IVehicle {
    color: string;
    model_no: number;
}

Then what is the concept of interfaces that a class can't fetch the fields of an interface whose it implements, what if I don't implement an interface and directly declare the fields in a class. I am thinking that why developers of TypeScript added this thing? It doubles up the code; first make an interface, declare fields in there, than make a class (also add implements InterfaceName ) , then again declare those fields in that class, why?

because this is also valid:

interface IVehicle {
    color: string;
    model_no: number;
}

class ClownCar implements IVehicle {
    // can be a subset of original type
    public color: 'red' | 'green' | 'blue';
    public model_no: 250 = 250;
}

class NonEditableCar implements IVehicle {
    // can use getter or setters instead, doesn't have to be normal field
    get color() {
        return 'grey';
    }
    get model_no(){
        return 100;
    }
}

An interface just says that an instance will have those fields, it doesn't say it must match that exact type. The declaration you have in the class specifies that the implementation is to store an instance variable which needs to be initialized.

You can narrow instance variables and widen method call signatures while still implementing an interface:

interface VehicleCarrier {
    contents: IVehicle[];
    launch(count: number): void;
}

class AircraftCarrier implements VehicleCarrier {
    // this is more specific, and because the inteface forces you to write it you have to consider that
    // it should be more specific.
    public contents: (Plane | Submarine)[];
    // can extend call signatures for methods
    public launch(count: number, type: 'plane' | 'sub' = 'plane') {}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM