类的创建
//使用class关键字来定义一个类
//直接定义的属性是实例属性,需要通过对象的实例去访问
//const per = new Person();
//per.name
//使用static开头的属性是静态属性,可以直接通过类去访问
//Person.gender
class Person{
//在属性前使用static关键字可以定义类属性(静态属性)
static gender:string = "男";
//定义实例属性
name:string = "嚣张";
age:number = 15;
//方法
//如果方法以static开头则用类去调用,否则用实例去调用
sayHello(){
console.log('你好');
}
}
const per = new Person();
console.log(Person.gender);
console.log(per.name,per.age);
构造函数
class Dog{
name:string;
age:number;
//constructor被称为构造函数
//构造函数会在对象创建时调用
constructor(name:string,age:number){
//在实例方法中,this表示当前实例
//在构造函数中当前对象就是当前新建的那个对象
//可以通过this向新建的对象中添加属性
this.name = name;
this.age = age;
}
bark(){
//在方法中可以通过this来表示当前调用方法的对象
alert("wangwang");
}
}
const dog = new Dog(name:'小黑',age:4);
const dog2 = new Dog(name:'小白',age:6);
console.log(dog);
继承
class Animal{
name:string;
age:number;
constructor(name:string,age:number){
this.name = name;
this.age = age;
}
sayHello(){
console.log("动物叫");
}
}
//使Dog继承Animal
//此时Animal成为父类 Dog是子类
//使用继承后,子类会拥有父类所有的方法和属性
//如果子类中添加了和父类相同的方法,子类会覆盖父类的方法
//这种子类覆盖父类的方法叫做方法的重写
class Dog extends Animal{
run(){
console.log(`${this.name}再跑!!!`)
}
sayHello(){
console.log("汪汪汪");
}
}
//使Cat继承Animal
class Cat extends Animal{
}
const dog = new Dog(name:"小黑",age:4);
const cat = new Cat(name:"小黑",age:4);
dog.run();
dog.sayHello();
super关键字
class Animal{
name:string;
constructor(name:string){
this.name = name;
}
sayHello(){
console.log("动物叫");
}
}
class Dog extends Animal{
age:number;
constructor(name:string,age:number){
//如果在子类中写了构造函数,在子类的构造函数中我们必须在子类对父类的构造函数进行调用
super(name);//这就是在调用父类的构造函数
this.age = age;
}
sayHello(){
//在类的方法中super就表示当前类的父类
super.sayHello();
}
}
const dog = new Dog(name:"小黑",age:15);
抽象类
//abstract 开头的类是抽象类
//抽象类和其他类的区别不大,只是不能用来创建对象
//抽象类就是专门用来继承的类
//抽象类中可以添加抽象方法
abstract class Animal{
name:string;
constructor(name:string){
this.name = name;
}
//定义一个抽象方法
//抽象方法使用abstract开头,没有方法体
//抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract sayHello():void
}
class Dog extends Animal{
sayHello(){
console.log("汪汪汪");
}
}
const dog = new Dog(name:"小黑");
dog.sayHello();
接口
//描述一个对象的类型
type myType = {
name:string.
age:number,
[propName:string]:any
};
//接口就是用来定义一个类的结构,用来定义一个类中应该包含哪些属性和方法
//同时接口也可以当成类型声明使用
interface myFace{
name:string,
age:number
}
interface myFace{
gender:string
}
const obj : myType = {
name:"zahngsan",
age:19
}
const obj : myFace= {
name:"zahngsan",
age:19,
gender:"女"
}
//接口可以在定义类的时候去限制类的结构
//接口中所有的属性都不能有实际的值
//接口只定义对象的接口,不考虑实际值
//在接口中所有的方法都是抽象方法
interface myInter{
name:string;
sayHello():void;
}
//定义类时,可以使类去实现一个接口
//实现接口就是类满足接口的要求
class Myclass implements myInter{
name:string;
constructor(name:string){
this.name = name;
}
sayHello(){
console.log(123);
}
}
属性的封装
class Person{
//TS可以在属性前添加属性的修饰符
//public修饰的属性可以在任意的位置进行修改
//private私有属性只能在类的内部进行访问(修改)
//protected受保护的属性,只能在当前类和当前类的子类中访问
//通过在类中添加方法使得私有属性可以被外部访问
private name:string,
private age:number;
constructor(name:string,age:number){
this.name = name;
this.age = age;
}
//getter setter他们称为属性的存取器
//定义方法用来获取name属性
getName(){
return this.name
}
//定义方法用来修改name属性
setName(value:string){
this.name = value;
}
//定义方法用来获取name属性
getAge(){
return this.age
}
//定义方法用来修改name属性
setAge(value:number){
if(value>=0){
this.age = value;
}
}
//Ts中设置getter
get name(){
return this.name;
}
set name(value:string){
this.name = value;
}
}
const per = new Person(name:"嚣张",age:18);
//属性是直接在对象中设置的,属性可以任意的被修改
//属性被任意更改导致我们对象的数据变得很不安全
console.log(per.getName());
per.setName('猪八戒');
per.setAge(55);
per.name;
per.name = '123';
class A{
protected name:string;
constructor(name:string){
this.name = name;
}
}
class B extends A{
test(){
console.log(this.name)
}
}
const b = new B(name:"123");
//b.name = '123';
class C{
//可以直接将属性定义在狗仔函数中
constructor(public name:string,public age:number){
}
}
const c = new C(name:"123",age:11);
泛型
//在定义函数或者类时,在遇到类型不明确的时候就可以用泛型
function fn<T>(a:T):T{
return a;
}
//可以直接调用拥有泛型的函数
fn(a:10);//不指定泛型,TS可以自动对类型进行推断
fn<string>(a:"hello");//指定泛型
//泛型可以同时指定多个
function fn2<T,K>(a:T,b:K):T{
console.log(b)
return a;
}
fn2<number,string>(a:123,b:"hello");
interface Inter{
length:number;
}
//T extends Inter 表示泛型T必须是Inter的实现类(子类)
function fn3<T extends Inter>(a:T):number{
return a.length;
}
//表示要传有length属性的值
fn3(a:"123");
class Myclass<T>{
name:T;
constructor(name:T){
this.name = name;
}
}
const mc = new Myclass(name:"孙文");
const mcw = new Myclass<string>(name:"孙文");