Interfaces and classes
Class implementation interface
This is the 19th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021
The basic use
Simple to use
class Person {
// This defines the types of name and age in the instance
name: string
age: number
// The data type of the constructor argument is defined here
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
Copy the code
inheritance
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
class Student extends Person {
sno: string
constructor(name: string, age: number, sno: string) {
super(name, age)
this.sno = sno
}
}
Copy the code
The modifier
public | Public, available outside of both subclasses and class definitions | The default value |
---|---|---|
protected | Accessible in subclasses, not outside the class definition | |
private | Private, can only be used inside a class, not accessible outside the class or in a subclass | |
readonly | Defining read-only properties |
public
class Parent {
// Default is public
name: string
constructor(name: string) {
// The public attribute can be accessed in the class itself
this.name = name
}
}
class Child extends Parent{
constructor(name: string) {
super(name)
}
printName() {
// The public attribute can be accessed in subclasses
console.log(this.name)
}
}
const childInstance = new Child('Klaus')
Public attributes can be accessed outside the class definition
console.log(childInstance.name) // => Klaus
childInstance.printName() // => Klaus
Copy the code
protected
class Parent {
protected name: string
constructor(name: string) {
// The private attribute can be used within the class itself
this.name = name
}
}
class Child extends Parent{
constructor(name: string) {
super(name)
}
printName() {
// Protected properties can be accessed in subclasses
console.log(this.name)
}
}
const childInstance = new Child('Klaus')
// Protected attributes cannot be accessed outside the class definition
// console.log(childInstance.name) // error
childInstance.printName() // => Klaus
Copy the code
class Parent {
protected name: string
// restrict the constructor when protected
// Indicates that the class can only be inherited but not instantiated
protected constructor(name: string) {
this.name = name
}
}
class Child extends Parent{
constructor(name: string) {
super(name)
}
printName() {
console.log(this.name)
}
}
// console.log(new Parent('Alex')) // error
Copy the code
private
class Parent {
private name: string
constructor(name: string) {
// The private attribute can be used within the class itself
this.name = name
}
}
class Child extends Parent{
constructor(name: string) {
super(name)
}
printName() {
// Private attributes cannot be accessed in subclasses
// console.log(this.name) // error}}const childInstance = new Child('Klaus')
// Protected attributes cannot be accessed outside the class definition
// console.log(childInstance.name) // error
Copy the code
class Parent {
private name = 'Klaus'
}
const per = new Parent()
// TS only statically analyzes the type of code at compile time, and does not actually execute the code
// So the private property in TS just prevents you from using it as much as possible
// The property is not actually made private
console.log(per) // => { name: 'Klaus' }
Copy the code
readonly
class Parent {
// The name attribute is read-only
readonly name: string
constructor(name: string) {
this.name = name
}
}
const instance = new Parent('Klaus')
// Attributes decorated with readonly are read-only and cannot be modified
// instance.name = 'Alex' // error
Copy the code
Parameter properties
class Parent {
// Modify the instance attributes here
protected readonly name: string
constructor(name: string) {
this.name = name
}
}
const instance = new Parent('Klaus')
Copy the code
But in TS, class attribute modifications and definitions can actually be put together using syntactic sugar, which is called parameter properties
class Parent {
// Define parameter attributes
constructor(protected readonly name: string) {
this.name = name
}
}
const instance = new Parent('Klaus')
Copy the code
Static attributes
class Parent {
// Define the public static attribute username
public static username = 'Klaus'
}
console.log(Parent.username) // => Klaus
Copy the code
Optional attribute
class Parent {
name: string // Name is a mandatory attributeage? :number = 18 // age is optional. The default value is 18
// The uid attribute is optional. The default is undefined
constructor(name: string, age? :number.publicuid? :string) {
this.name = name
// Undefined is assigned to the instance attribute age
// The value of age is undefined
this.age = age
}
}
console.log(new Parent('Klaus')) // => { uid: undefined, age: undefined, name: 'Klaus' }
Copy the code
accessor
class Person {
private _name: string = ' '
get name() {
return this._name
}
set name(value: string) {
this._name = value
}
}
const per = new Person()
per.name = 'Klaus'
console.log(per.name) // => Klaus
Copy the code
An abstract class
Abstract classes can only be inherited by subclasses, not instantiated
Abstract classes can be used to constrain attributes or methods that must exist in a subclass
An abstract class can have abstract properties and methods, and it can have both implemented properties and methods
An abstract class may inherit from another abstract class, in which case the abstract methods or properties of the parent may not be implemented in the child
abstract class Parent {
// Abstract methods define formats
// abstract [attribute descriptor](parameter list): return value type
abstractprint(value? :string) :void
}
// An abstract subclass may implement an abstract property or method in an abstract superclass
abstract class Child extends Parent {
pirntChildName() {
console.log(Child.name)
}
}
// If a class inherits from an abstract class, the class must implement properties and methods in the abstract class
class Instance extends Child {
print(value: string) {
console.log(value)
}
}
const inst = new Instance()
inst.print('Hello TypeScript')
inst.pirntChildName()
Copy the code
abstract class Parent { abstract print(value? : string):void
abstract age: number
If a private attribute in a class (including an abstract class) is not assigned in the constructor
// Then it must be initialized
private _name:string = ' '
abstract get name() :string// Special: Do not add the type annotation of return value when defining the type of attribute accessorabstract set name(value: string)}class Child extends Parent {
name: string
age: number
constructor(name: string, age: number) {
super(a)this.name = name
this.age = age
}
print(value: string) {
console.log(value)
}
}
Copy the code
Class types
class Person {
name: string
constructor(name: string) {
this.name = name
}
}
// The type of per is Person
Person is both a type and a value
let per = new Person('Klaus')
class Animal extends Person {
age: number
constructor(name: string, age: number) {
super(name)
this.age = age
}
}
// Per is of type Person
// Animal is the type of Person subclass
// Therefore conforms to the type compatibility, can be assigned
per = new Animal('Dog'.8)
Copy the code
Class implementation interface
We can have a class implement an interface that constrains the corresponding instance structure
interface IPerson {
name: string
}
class Person implements IPerson {
name: string = ' '
}
Copy the code
Interface inheritance class
class Person {
name: string = ' '
}
interface IFoo extends Person {}
/ / equivalent to the
/* interface IFoo { name: string } */
const foo: IFoo = {
name: 'Klaus'
}
Copy the code
class Person {
protected name: string = ' '
}
// Protected attributes in a class are also implemented by class inheritance
// The interface can only be used by the class itself or a subclass of the class
interface IFoo extends Person {}
class Foo extends Person implements IFoo {}
Copy the code