面向对象
面向对象,Object Oriented,软件开发 ,一种编程范式。
面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、 管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的 ,是计算机编程技术发展到一定阶段后的产物。
面向对象的三大特性:封装、继承、多态。
TypeScript面向对象,类 (class)
1、static关键字,表示一个静态属性,通过类访问。
2、readonly关键字,表示一个只读属性,不能修改属性,构造函数可初始化。
构造函数和this关键字
1、constructor函数,称为构造函数,对象创建时调用。
2、在实例 中,this就表示当前当前的实例。
继承(extends)和super关键字
1、子类写了constructor构造函数必须使用super继承父类constructor构造函数的属性
2、通过继承可以将多个类 有的代码写在一个父类中,继承后子类将会拥有父类所有的 和属性。
3、 重写,子类中添加了和父类相同的 ,子类方***覆盖掉父类的
抽象(abstract)
1、以abstract开头的类是抽象类,抽象类不能实例化,事专门用来被继承的类。
2、抽象类中可以添加抽象 ,非抽象类中不可以有抽象 。
3、抽象 使用abstract开头,没有 体,只能定义在抽象类中,子类必须对抽象 进行重写。
接口(interface)
1、接口的作用类似于抽象类,不同点在于接口中的所有函数和属性都是没有实值的,接口中的所有 都是抽象 。
2、接口主要负责定义一个类的结构,限制一个对象的接口,对象只有包含接口中定义的所有属性和 时才能匹配接口。
3、一个类去实现接口,实现接口时类中要包括接口中的所有属性。
封装和属性的封装
1、private修饰符,私有的属性,私有属性只能在类内部进行访问修改。
2、protected修饰符,受保护的属性,只能在当前类和当前类的子类中访问。
3、public修饰符,共有的属性,修饰的属性可以再任意位置访问修改默认值。
4、getter 用来读取属性。
5、setter 迎来设置属性。
6、getter和setter被统一称为属性的存储器,定义时在 之前添加get和set,调用的时候直接通过点语法调用。
代码案例
案例1:
class MyUser { static desc: string = "用户类"; // 使用static开头的属性是静态属性(类属性),可以直接通过类去访问 readonly id: number = 1000004; // readonly开头的属性表示一个只读的属性无法修改 name: string = "张三"; age: number = 28; toString() { return "id=" + this.id + ",name=" + this.name + ",age=" + this.age; } } let myUser = new MyUser(); console.log("myUser=", myUser); // myUser= MyUser { id: 1000004, name: '张三', age: 28 } console.log("myUser.desc=", MyUser.desc); // myUser.desc= 用户类
案例2:
class MyUser2 { readonly id: number; name: string; age: number; /** * 构造函数和this * @param id * @param name * @param age */ constructor(id: number, name: string, age: number) { this.id = id; this.name = name; this.age = age; } toString() { return "id=" + this.id + ",name=" + this.name + ",age=" + this.age; } } let myUser2 = new MyUser2(1000001, "孔子", 2000); console.log("myUser2=", myUser2); // myUser2= MyUser2 { id: 1000001, name: '孔子', age: 2000 }
案例3:
( function () { /** * 以abstract开头的类是抽象类,抽象类和其他类区别不大,不能用来创建对象 * 抽象类就是专门用来被继承的类 * 抽象类中可以添加抽象 */ abstract class MyUser3 { readonly id: number; name: string; age: number; /** * 构造函数和this * @param id * @param name * @param age */ constructor(id: number, name: string, age: number) { this.id = id; this.name = name; this.age = age; } toString() { return "id=" + this.id + ",name=" + this.name + ",age=" + this.age; } /** * 抽象 使用 abstract开头,没有 体 * 抽象 只能定义在抽象类中,子类必须对抽象 进行重写 */ abstract work():void ; } class MyEmployee extends MyUser3 { /** * 构造函数 * @param id * @param name * @param age */ constructor(id: number, name: string, age: number) { super(id, name, age); } work() { console.log("雇员,id=" + this.id + ",name=" + this.name + "在工作"); } } class MyManager extends MyUser3 { work() { console.log("经理,id=" + this.id + ",name=" + this.name + "在工作"); } } let myEmployee = new MyEmployee(1, "沙僧", 501); // myEmployee= MyEmployee { id: 1, name: '沙僧', age: 501 } console.log("myEmployee=", myEmployee); myEmployee.work(); // 雇员,id=1,name=沙僧在工作 let myManager = new MyManager(1, "唐僧", 500); // myManager= MyManager { id: 1, name: '唐僧', age: 500 } console.log("myManager=", myManager); myManager.work(); // 经理,id=1,name=唐僧在工作 } )();
案例4:
interface MyWorker{ work():void; } class MyUser4 implements MyWorker { readonly id: number = 1000004; // readonly开头的属性表示一个只读的属性无法修改 name: string = "张三"; age: number = 28; toString() { return "id=" + this.id + ",name=" + this.name + ",age=" + this.age; } work() { console.log("用户,id=" + this.id + ",name=" + this.name + "在工作"); } } let myUser4 = new MyUser4(); // myUser4= MyUser4 { id: 1000004, name: '张三', age: 28 } console.log("myUser4=", myUser4); myUser4.work(); //用户,id=1000004,name=张三在工作
案例5:
(function () { // 定义一个表示人的类 class Person { // TS可以在属性前添加属性的修饰符 /* * public,修饰的属性可以在任意位置访问(修改) 默认值 * private,私有属性,私有属性只能在类内部进行访问(修改) * - 通过在类中添加 使得私有属性可以被外部访问 * protected 受包含的属性,只能在当前类和当前类的子类中访问(修改) * * */ private _name: string; private _age: number; /** * 构造函数 * * @param name * @param age */ constructor(name: string, age: number) { this._name = name; this._age = age; } /* * getter 用来读取属性 * setter 用来设置属性 * - 它们被称为属性的存取器 * */ // TS中设置getter 的方式 get name() { // console.log('get name()执行了!!'); return this._name; } set name(value) { this._name = value; } get age() { return this._age; } set age(value) { if (value >= 0) { this._age = value } } } const person = new Person('孙悟空', 18); /* * 现在属性是在对象中设置的,属性可以任意的被修改, * 属性可以任意被修改将会导致对象中的数据变得非常不安全 * */ // person.setName('猪八戒'); // person.setAge(33); person.name = '猪八戒'; person.age = 33; console.log(person); class A { //protected是保护的属性,只能在当前类和子类中设置 //protected只能在当前类和当前类的子类中设置 protected num: number; constructor(num: number) { this.num = num; } } class B extends A { test() { console.log(this.num); } } const b = new B(123456789); // b.num = 33; // 属性“num”受保护,只能在类“A”及其子类中访问。 class C1 { name: string; age: number // 可以直接将属性定义在构造函数中 constructor(name: string, age: number) { this.name = name; this.age = age; } } const c1 = new C1('沙僧', 111222333); console.log(c1); // C1 { name: '沙僧', age: 111222333 } class C2 { // 直接将属性定义在构造函数中 constructor(public name: string, public age: number) { } } const c2 = new C2('沙僧', 111222333); console.log(c2); // C2 { name: '沙僧', age: 111222333 } })();