标签:11 tsxclass return Point number TS new class
# TS Class的补充
## 定义类和成员
```tsx
class Point {
x: number
y: number
constructor(x : number, y : number){
this.x = x
this.y = y
}
public add(p : Point) : Point {
return new Point(p.x + this.x, p.y + this.y)
}
}
const p = new Point(0, 0)
const newP = p.add(new Point(1, 1))
console.log(newP)
```
## 成员函数的重载
```tsx
class Point {
// ...
public add(x : number, y : number) : Point;
public add(p : Point) : Point;
public add(x : number | Point, y? : number) {
if(typeof x === 'number') {
return new Point(this.x + x , this.y + y!)
}
const p = x
return new Point(this.x + p.x, this.y + p.y)
}
}
const p = new Point(0, 0)
const newP = p.add(new Point(1, 1))
console.log(newP)
```
重载可以获得更好的书写提示体验。
## Getter / Setter
获取和设置变成两个方法,隐藏了内部具体的实现。
```tsx
class C {
_length = 0;
get length() {
return this._length;
}
set length(value) {
this._length = value;
}
}
```
不推荐这样的实现(小师叔个人风格建议),推荐:
```tsx
class C {
_length = 0;
getLength() {
return this._length;
}
setLength(value) {
this._length = value;
}
}
```
## 索引器
```tsx
class Arr<T> {
[i : number] : T
}
const a = new Arr<number>()
a[10] = 100
console.log(a[10]) // 100
```
## 继承
### 类型继承
```tsx
interface BasicAddress {
name?: string;
street: string;
city: string;
country: string;
postalCode: string;
}
interface AddressWithUnit extends BasicAddress {
unit: string;
}
```
### 类的继承
```tsx
class Animal {
move() {
console.log("Moving along!");
}
}
class Dog extends Animal {
woof(times: number) {
for (let i = 0; i < times; i++) {
console.log("woof!");
}
}
}
```
实战中尽量使用组合:
```tsx
interface Movable {
move() : void;
}
class Dog implements Movable {
move () {
console.log('move dog')
}
}
```
思考:实现接口和继承的区别是什么?
思考:为什么用Movable而不是Animal作为接口?
或者泛型:
```tsx
class Movable<T extends Animal> {
animal : T
move(){
console.log(`${animal.getName()} is moving`)
}
}
```
划重点:继承会加重耦合,组合和泛型不会。
## 成员可见域
- public
- protected
- private
`public` `private` `protected` 这3个和其他语言一样,具体的:
`public` 成员允许所有程序访问,如果不标识任何约束,那么默认就是`public` 。
```ts
class Point {
x : number
}
// x可以被任意程序访问
```
`private` 成员只允许在当前类中访问。
```tsx
class Point {
private x : number
constructor(){
this.x = x // 成立
}
getX(){
return this.x
}
}
const p = new Point()
console.log(p.x)
// Error : Property 'x' is private and only accessible within class 'Point'.ts(2341)
```
`protected` 允许在当前类和它的继承类中访问成员。
```tsx
class Animal {
private _name1;
protected _name2;
}
class Dog extends Animal{
getName1(){
return this._name1 // Error
}
getName2(){
return this._name2 // pass
}
}
```
## 静态成员
```tsx
class MyClass {
static x = 0;
static printX() {
console.log(MyClass.x);
}
}
console.log(MyClass.x);
MyClass.printX();
```
静态成员和类的实例没有关系,静态成员、静态方法都绑定在类型本身上。
静态成员也会继承:
```tsx
class Base {
static getGreeting() {
return "Hello world";
}
}
class Derived extends Base {
myGreeting = Derived.getGreeting();
}
```
保留的特殊静态成员名称:
```tsx
class S {
static name = "S!";
// Error : Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'S'.
}
```
### 为什么没有静态类?
在 Java中有静态类, 静态类是相对类的嵌套的概念,在JS虽然也存在类的嵌套,但是遵循B包的逻辑,比如:
```tsx
class A {
x : number
foo(){
const y = 0
class B{
bar(){
this.x // Property 'x' does not exist on type 'B'
console.log(y)
}
}
return B
}
}
```
因为有B包的逻辑,就不太适合再增加,让嵌套类可以访问外部类成员的逻辑了。 逻辑太复杂,不利于程序员写程序。
## 类型守卫
```tsx
class FileSystemObject {
isFile(): this is FileRep {
return this instanceof FileRep;
}
isDirectory(): this is Directory {
return this instanceof Directory;
}
isNetworked(): this is Networked & this {
return this.networked;
}
constructor(public path: string, private networked: boolean) {}
}
class FileRep extends FileSystemObject {
constructor(path: string, public content: string) {
super(path, false);
}
}
class Directory extends FileSystemObject {
children: FileSystemObject[];
}
interface Networked {
host: string;
}
const fso: FileSystemObject = new FileRep("foo/bar.txt", "foo");
if (fso.isFile()) {
fso.content;
//const fso: FileRep
} else if (fso.isDirectory()) {
fso.children;
//const fso: Directory
} else if (fso.isNetworked()) {
fso.host;
//const fso: Networked & FileSystemObject
}
```
## 抽象类
抽象类不可以实例化
```tsx
abstract class Base {
abstract getName(): string;
printName() {
console.log("Hello, " + this.getName());
}
}
const b = new Base();
// Cannot create an instance of an abstract class.
```
必须继承:
```tsx
class Derived extends Base {
getName() {
return "world";
}
}
const d = new Derived();
d.printName();
```
## 类型的关系
TS会通过成员去思考类型是否一致:
```tsx
class Point1 {
x = 0;
y = 0;
}
class Point2 {
x = 0;
y = 0;
}
// OK
const p: Point1 = new Point2();
```
另一个例子:
```tsx
class Person {
name: string;
age: number;
}
class Employee {
name: string;
age: number;
salary: number;
}
// OK
const p: Person = new Employee();
```
最后一个例子:
```tsx
class Empty {}
function fn(x: Empty) {
// can't do anything with 'x', so I won't
}
// All OK!
fn(window);
fn({});
fn(fn);
```
标签:11,tsxclass,return,Point,number,TS,new,class 来源: https://www.cnblogs.com/anans/p/15981974.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。