📜  Typescript 类中属性/方法的默认可见性是什么?

📅  最后修改于: 2022-05-13 01:56:17.290000             🧑  作者: Mango

Typescript 类中属性/方法的默认可见性是什么?

在 Typescript 中,默认情况下,Typescript 类中所有属性或方法的可见性都是“ public ”。公开的方法可以从任何地方访问,它没有任何限制。成员可见性分为三种类型: publicprivateprotected。

示例 1:具有公共成员可见性的类

可以从任何地方访问公共函数和属性。默认情况下,所有方法和属性都是“ public ”。在这个例子中,我们创建了一个类 student,它有两个属性和一个方法。我们使用 public 关键字来表示该函数具有公共可见性,但默认情况下所有属性和方法都是公共的,我们不需要指定。

Javascript
class Student {
  name: string;
  id: number;
  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
  public student_details() {
    console.log(
      "my name is : " +
        this.name +
        " my roll no is : " +
        `${this.id.toString()}`
    );
  }
}
  
let obj = new Student("rahul", 367236);
obj.student_details();


Javascript
class Student {
  protected name: string;
  id: number;
  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
  protected student_details() {
    console.log(
      "my name is : " +
        this.name +
        " my roll no is : " +
        `${this.id.toString()}`
    );
  }
  student_name() {
    console.log("My name is : " + self.name);
  }
}
  
class classRepresentative extends Student {
  detail() {
    console.log("I am the class representative, my name is :" 
      + this.name);
  }
}
  
let obj = new Student("rahul", 367236);
let obj1 = new classRepresentative("samuel", 287636);
  
obj.name; // Error as name is protected
obj.student_name(); // No error
obj.student_details(); // Error
obj1.detail(); // No error
obj1.student_details(); //Error


Javascript
class Student {
  private name: string;
  id: number;
  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
  private student_details() {
    console.log(
      "my name is : " +
        this.name +
        " my roll no is : " +
        `${this.id.toString()}`
    );
  }
  student_name() {
    console.log("My name is : " + self.name);
  }
}
class classRepresentative extends Student {
  detail() {
    console.log("I am the class representative, my name is :"
      + this.name);
  }
    
}
  
let obj = new Student("rahul", 367236);
let obj1 = new classRepresentative("samuel", 287636);
  
obj.name; // Error as name is private
obj.student_name(); // No error
obj.student_details(); // Error
obj1.detail(); // No error
obj1.student_details(); // Error


输出:创建一个 obj 并调用 student_details() 方法。

my name is : rahul my roll no is : 367236

示例 2:具有受保护成员可见性的类

具有“受保护”可见性的成员或属性只能在其类或其子类中访问。在此示例中,在声明函数时和属性“名称”之前使用了protected关键字。类classRepresentative 派生自类Student。当我们尝试从外部访问“name”时,它会返回一个错误,因为我们可以使用它并且只能在该类或其子类中访问它。 name 也用在 student_name()函数中,但不会引发错误,因为它在类中。由于 student_details() 受到保护,因此无法从外部访问它。

Javascript

class Student {
  protected name: string;
  id: number;
  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
  protected student_details() {
    console.log(
      "my name is : " +
        this.name +
        " my roll no is : " +
        `${this.id.toString()}`
    );
  }
  student_name() {
    console.log("My name is : " + self.name);
  }
}
  
class classRepresentative extends Student {
  detail() {
    console.log("I am the class representative, my name is :" 
      + this.name);
  }
}
  
let obj = new Student("rahul", 367236);
let obj1 = new classRepresentative("samuel", 287636);
  
obj.name; // Error as name is protected
obj.student_name(); // No error
obj.student_details(); // Error
obj1.detail(); // No error
obj1.student_details(); //Error

输出:

error TS2445: Property 'name' is protected and only accessible within 
class 'Student' and its subclasses.
    obj.name; // error as name is protected
        ~~~~

two.ts:131:5 - error TS2445: Property 'student_details' is protected and only accessible 
within class 'Student' and its subclasses.
    obj.student_details(); //error
        ~~~~~~~~~~~~~~~

two.ts:133:6 - error TS2445: Property 'student_details' is protected and only accessible 
within class 'Student' and its subclasses.
    obj1.student_details(); //error
         ~~~~~~~~~~~~~~~

示例 3:具有私有成员可见性的类

Private类似于 protected,但它也阻止子类访问成员。派生类无法提高其可见性,因为私有成员对派生类不可见。在前面的示例中,派生类在 detail()函数中使用属性 this.name 并且不会引发错误,因为该属性可以在子类中使用,但是当其可见性设置为私有时,无法在子类中访问它或派生类了。

Javascript

class Student {
  private name: string;
  id: number;
  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
  private student_details() {
    console.log(
      "my name is : " +
        this.name +
        " my roll no is : " +
        `${this.id.toString()}`
    );
  }
  student_name() {
    console.log("My name is : " + self.name);
  }
}
class classRepresentative extends Student {
  detail() {
    console.log("I am the class representative, my name is :"
      + this.name);
  }
    
}
  
let obj = new Student("rahul", 367236);
let obj1 = new classRepresentative("samuel", 287636);
  
obj.name; // Error as name is private
obj.student_name(); // No error
obj.student_details(); // Error
obj1.detail(); // No error
obj1.student_details(); // Error

输出:

error TS2341: Property 'name' is private and only accessible within class 'Student'.
        console.log("I am the class representative, my name is :" + this.name);
                                                                         ~~~~
                                                                         
two.ts:161:5 - error TS2341: Property 'name' is private and only accessible
 within class 'Student'.
    obj.name; // error as name is protected
        ~~~~

two.ts:163:5 - error TS2341: Property 'student_details' is private and only accessible 
within class 'Student'.
    obj.student_details(); //error
        ~~~~~~~~~~~~~~~

two.ts:165:6 - error TS2341: Property 'student_details' is private and only accessible 
within class 'Student'.
    obj1.student_details(); //error
         ~~~~~~~~~~~~~~~

参考: https://www.typescriptlang.org/docs/handbook/classes.html#public-private-and-protected-modifiers