-
TypeScript 是面向对象的 JavaScript。类描述了所创建的对象共同的属性和方法。TypeScript 支持面向对象的所有特性,比如 类、接口等。TypeScript 类定义方式如下:class class_name { // 类作用域}定义类的关键字为 class,后面紧跟类名,类可以包含以下几个模块(类的数据成员):字段 − 字段是类里面声明的变量。字段表示对象的有关数据。构造函数 − 类实例化时调用,可以为类的对象分配内存。方法 − 方法为对象要执行的操作。实例创建一个 Person 类:TypeScriptclass Person {}编译以上代码,得到以下 JavaScript 代码:JavaScriptvar Person = /** @class */ (function () { function Person() { } return Person;}());创建类的数据成员以下实例我们声明了类 Car,包含字段为 engine,构造函数在类实例化后初始化字段 engine。this 关键字表示当前类实例化的对象。注意构造函数的参数名与字段名相同,this.engine 表示类的字段。此外我们也在类中定义了一个方法 disp()。TypeScriptclass Car { // 字段 engine:string; // 构造函数 constructor(engine:string) { this.engine = engine } // 方法 disp():void { console.log("发动机为 : "+this.engine) } }编译以上代码,得到以下 JavaScript 代码:JavaScriptvar Car = /** @class */ (function () { // 构造函数 function Car(engine) { this.engine = engine; } // 方法 Car.prototype.disp = function () { console.log("发动机为 : " + this.engine); }; return Car;}());创建实例化对象我们使用 new 关键字来实例化类的对象,语法格式如下:var object_name = new class_name([ arguments ])类实例化时会调用构造函数,例如:var obj = new Car("Engine 1")类中的字段属性和方法可以使用 . 号来访问:// 访问属性obj.field_name // 访问方法obj.function_name()完整实例以下实例创建来一个 Car 类,然后通过关键字 new 来创建一个对象并访问属性和方法:TypeScriptclass Car { // 字段 engine:string; // 构造函数 constructor(engine:string) { this.engine = engine } // 方法 disp():void { console.log("函数中显示发动机型号 : "+this.engine) } } // 创建一个对象var obj = new Car("XXSY1") // 访问字段console.log("读取发动机型号 : "+obj.engine) // 访问方法obj.disp()编译以上代码,得到以下 JavaScript 代码:JavaScriptvar Car = /** @class */ (function () { // 构造函数 function Car(engine) { this.engine = engine; } // 方法 Car.prototype.disp = function () { console.log("函数中显示发动机型号 : " + this.engine); }; return Car;}());// 创建一个对象var obj = new Car("XXSY1");// 访问字段console.log("读取发动机型号 : " + obj.engine);// 访问方法obj.disp();输出结果为:读取发动机型号 : XXSY1函数中显示发动机型号 : XXSY1类的继承TypeScript 支持继承类,即我们可以在创建类的时候继承一个已存在的类,这个已存在的类称为父类,继承它的类称为子类。类继承使用关键字 extends,子类除了不能继承父类的私有成员(方法和属性)和构造函数,其他的都可以继承。TypeScript 一次只能继承一个类,不支持继承多个类,但 TypeScript 支持多重继承(A 继承 B,B 继承 C)。语法格式如下:class child_class_name extends parent_class_name实例类的继承:实例中创建了 Shape 类,Circle 类继承了 Shape 类,Circle 类可以直接使用 Area 属性:TypeScriptclass Shape { Area:number constructor(a:number) { this.Area = a } } class Circle extends Shape { disp():void { console.log("圆的面积: "+this.Area) } } var obj = new Circle(223); obj.disp()编译以上代码,得到以下 JavaScript 代码:JavaScriptvar __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); };})();var Shape = /** @class */ (function () { function Shape(a) { this.Area = a; } return Shape;}());var Circle = /** @class */ (function (_super) { __extends(Circle, _super); function Circle() { return _super !== null && _super.apply(this, arguments) || this; } Circle.prototype.disp = function () { console.log("圆的面积: " + this.Area); }; return Circle;}(Shape));var obj = new Circle(223);obj.disp();输出结果为:圆的面积: 223需要注意的是子类只能继承一个父类,TypeScript 不支持继承多个类,但支持多重继承,如下实例:TypeScriptclass Root { str:string; } class Child extends Root {} class Leaf extends Child {} // 多重继承,继承了 Child 和 Root 类 var obj = new Leaf(); obj.str ="hello" console.log(obj.str)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); };})();var Root = /** @class */ (function () { function Root() { } return Root;}());var Child = /** @class */ (function (_super) { __extends(Child, _super); function Child() { return _super !== null && _super.apply(this, arguments) || this; } return Child;}(Root));var Leaf = /** @class */ (function (_super) { __extends(Leaf, _super); function Leaf() { return _super !== null && _super.apply(this, arguments) || this; } return Leaf;}(Child)); // 多重继承,继承了 Child 和 Root 类var obj = new Leaf();obj.str = "hello";console.log(obj.str);输出结果为:hello
-
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。TypeScript 接口定义如下:interface interface_name { }实例以下实例中,我们定义了一个接口 IPerson,接着定义了一个变量 customer,它的类型是 IPerson。customer 实现了接口 IPerson 的属性和方法。TypeScriptinterface IPerson { firstName:string, lastName:string, sayHi: ()=>string } var customer:IPerson = { firstName:"Tom", lastName:"Hanks", sayHi: ():string =>{return "Hi there"} } console.log("Customer 对象 ") console.log(customer.firstName) console.log(customer.lastName) console.log(customer.sayHi()) var employee:IPerson = { firstName:"Jim", lastName:"Blakes", sayHi: ():string =>{return "Hello!!!"} } console.log("Employee 对象 ") console.log(employee.firstName) console.log(employee.lastName)需要注意接口不能转换为 JavaScript。 它只是 TypeScript 的一部分。编译以上代码,得到以下 JavaScript 代码:JavaScriptvar customer = { firstName: "Tom", lastName: "Hanks", sayHi: function () { return "Hi there"; }};console.log("Customer 对象 ");console.log(customer.firstName);console.log(customer.lastName);console.log(customer.sayHi());var employee = { firstName: "Jim", lastName: "Blakes", sayHi: function () { return "Hello!!!"; }};console.log("Employee 对象 ");console.log(employee.firstName);console.log(employee.lastName);输出结果为:Customer 对象TomHanksHi thereEmployee 对象JimBlakes联合类型和接口以下实例演示了如何在接口中使用联合类型:TypeScriptinterface RunOptions { program:string; commandline:string[]|string|(()=>string); } // commandline 是字符串var options:RunOptions = {program:"test1",commandline:"Hello"}; console.log(options.commandline) // commandline 是字符串数组options = {program:"test1",commandline:["Hello","World"]}; console.log(options.commandline[0]); console.log(options.commandline[1]); // commandline 是一个函数表达式options = {program:"test1",commandline:()=>{return "**Hello World**";}}; var fn:any = options.commandline; console.log(fn());编译以上代码,得到以下 JavaScript 代码:JavaScript// commandline 是字符串var options = { program: "test1", commandline: "Hello" };console.log(options.commandline);// commandline 是字符串数组options = { program: "test1", commandline: ["Hello", "World"] };console.log(options.commandline[0]);console.log(options.commandline[1]);// commandline 是一个函数表达式options = { program: "test1", commandline: function () { return "**Hello World**"; } };var fn = options.commandline;console.log(fn());输出结果为:HelloHelloWorld**Hello World**接口和数组接口中我们可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串。TypeScriptinterface namelist { [index:number]:string } var list2:namelist = ["John",1,"Bran"] // 错误元素 1 不是 string 类型interface ages { [index:string]:number } var agelist:ages; agelist["John"] = 15 // 正确 agelist[2] = "nine" // 错误接口继承接口继承就是说接口可以通过其他接口来扩展自己。Typescript 允许接口继承多个接口。继承使用关键字 extends。单接口继承语法格式:Child_interface_name extends super_interface_name多接口继承语法格式:Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name继承的各个接口使用逗号 , 分隔。单继承实例TypeScriptinterface Person { age:number } interface Musician extends Person { instrument:string } var drummer = <Musician>{}; drummer.age = 27 drummer.instrument = "Drums" console.log("年龄: "+drummer.age)console.log("喜欢的乐器: "+drummer.instrument)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar drummer = {};drummer.age = 27;drummer.instrument = "Drums";console.log("年龄: " + drummer.age);console.log("喜欢的乐器: " + drummer.instrument);输出结果为:年龄: 27喜欢的乐器: Drums多继承实例TypeScriptinterface IParent1 { v1:number } interface IParent2 { v2:number } interface Child extends IParent1, IParent2 { } var Iobj:Child = { v1:12, v2:23} console.log("value 1: "+Iobj.v1+" value 2: "+Iobj.v2)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar Iobj = { v1: 12, v2: 23 };console.log("value 1: " + Iobj.v1 + " value 2: " + Iobj.v2);输出结果为:value 1: 12 value 2: 23
-
联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值。注意:只能赋值指定的类型,如果赋值其它类型就会报错。创建联合类型的语法格式如下:Type1|Type2|Type3 实例声明一个联合类型:TypeScriptvar val:string|number val = 12 console.log("数字为 "+ val) val = "Runoob" console.log("字符串为 " + val)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar val;val = 12;console.log("数字为 " + val);val = "Runoob";console.log("字符串为 " + val);输出结果为:数字为 12字符串为 Runoob如果赋值其它类型就会报错:var val:string|number val = true 也可以将联合类型作为函数参数使用:TypeScriptfunction disp(name:string|string[]) { if(typeof name == "string") { console.log(name) } else { var i; for(i = 0;i<name.length;i++) { console.log(name[i]) } } } disp("Runoob") console.log("输出数组....") disp(["Runoob","Google","Taobao","Facebook"])编译以上代码,得到以下 JavaScript 代码:JavaScriptfunction disp(name) { if (typeof name == "string") { console.log(name); } else { var i; for (i = 0; i < name.length; i++) { console.log(name[i]); } }}disp("Runoob");console.log("输出数组....");disp(["Runoob", "Google", "Taobao", "Facebook"]);输出结果为:Runoob输出数组....RunoobGoogleTaobaoFacebook联合类型数组我们也可以将数组声明为联合类型:TypeScriptvar arr:number[]|string[]; var i:number; arr = [1,2,4] console.log("**数字数组**") for(i = 0;i<arr.length;i++) { console.log(arr[i]) } arr = ["Runoob","Google","Taobao"] console.log("**字符串数组**") for(i = 0;i<arr.length;i++) { console.log(arr[i]) }编译以上代码,得到以下 JavaScript 代码:JavaScriptvar arr;var i;arr = [1, 2, 4];console.log("**数字数组**");for (i = 0; i < arr.length; i++) { console.log(arr[i]);}arr = ["Runoob", "Google", "Taobao"];console.log("**字符串数组**");for (i = 0; i < arr.length; i++) { console.log(arr[i]);}输出结果为:**数字数组**124**字符串数组**RunoobGoogleTaobao
-
数组对象是使用单独的变量名来存储一系列的值。数组非常常用。假如你有一组数据(例如:网站名字),存在单独变量如下所示:var site1="Google";var site2="Runoob";var site3="Taobao";如果有 10 个、100 个这种方式就变的很不实用,这时我们可以使用数组来解决:var sites:string[]; sites = ["Google","Runoob","Taobao"]这样看起来就简洁多了。TypeScript 声明数组的语法格式如下所示:var array_name[:datatype]; //声明 array_name = [val1,val2,valn..] //初始化或者直接在声明时初始化:var array_name[:data type] = [val1,val2…valn]如果数组声明时未设置类型,则会被认为是 any 类型,在初始化时根据第一个元素的类型来推断数组的类型。实例创建一个 number 类型的数组:var numlist:number[] = [2,4,6,8]TypeScriptvar sites:string[]; sites = ["Google","Runoob","Taobao"] console.log(sites[0]); console.log(sites[1]);编译以上代码,得到以下 JavaScript 代码:JavaScriptvar sites;sites = ["Google", "Runoob", "Taobao"];console.log(sites[0]);console.log(sites[1]);输出结果为:GoogleRunoob以下实例我们在声明时直接初始化:TypeScriptvar nums:number[] = [1,2,3,4] console.log(nums[0]); console.log(nums[1]); console.log(nums[2]); console.log(nums[3]);编译以上代码,得到以下 JavaScript 代码:JavaScriptvar nums = [1, 2, 3, 4];console.log(nums[0]);console.log(nums[1]);console.log(nums[2]);console.log(nums[3]);输出结果为:1 2 3 4 Array 对象我们也可以使用 Array 对象创建数组。Array 对象的构造函数接受以下两种值:表示数组大小的数值。初始化的数组列表,元素使用逗号分隔值。实例指定数组初始化大小:TypeScriptvar arr_names:number[] = new Array(4) for(var i = 0; i<arr_names.length; i++) { arr_names[i] = i * 2 console.log(arr_names[i]) }编译以上代码,得到以下 JavaScript 代码:JavaScriptvar arr_names = new Array(4);for (var i = 0; i < arr_names.length; i++) { arr_names[i] = i * 2; console.log(arr_names[i]);}输出结果为:0246以下实例我们直接初始化数组元素:TypeScriptvar sites:string[] = new Array("Google","Runoob","Taobao","Facebook") for(var i = 0;i<sites.length;i++) { console.log(sites[i]) }编译以上代码,得到以下 JavaScript 代码:JavaScriptvar sites = new Array("Google", "Runoob", "Taobao", "Facebook");for (var i = 0; i < sites.length; i++) { console.log(sites[i]);}输出结果为:GoogleRunoobTaobaoFacebook数组解构我们也可以把数组元素赋值给变量,如下所示:TypeScriptvar arr:number[] = [12,13] var[x,y] = arr // 将数组的两个元素赋值给变量 x 和 yconsole.log(x) console.log(y)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar arr = [12, 13];var x = arr[0], y = arr[1]; // 将数组的两个元素赋值给变量 x 和 yconsole.log(x);console.log(y);输出结果为:1213数组迭代我们可以使用 for 语句来循环输出数组的各个元素:TypeScriptvar j:any; var nums:number[] = [1001,1002,1003,1004] for(j in nums) { console.log(nums[j]) }编译以上代码,得到以下 JavaScript 代码:JavaScriptvar j;var nums = [1001, 1002, 1003, 1004];for (j in nums) { console.log(nums[j]);}输出结果为:1001100210031004多维数组一个数组的元素可以是另外一个数组,这样就构成了多维数组(Multi-dimensional Array)。最简单的多维数组是二维数组,定义方式如下:var arr_name:datatype[][]=[ [val1,val2,val3],[v1,v2,v3] ]TypeScriptvar multi:number[][] = [[1,2,3],[23,24,25]] console.log(multi[0][0]) console.log(multi[0][1]) console.log(multi[0][2]) console.log(multi[1][0]) console.log(multi[1][1]) console.log(multi[1][2])编译以上代码,得到以下 JavaScript 代码:JavaScriptvar multi = [[1, 2, 3], [23, 24, 25]];console.log(multi[0][0]);console.log(multi[0][1]);console.log(multi[0][2]);console.log(multi[1][0]);console.log(multi[1][1]);console.log(multi[1][2]);输出结果为:123232425数组在函数中的使用作为参数传递给函数TypeScriptvar sites:string[] = new Array("Google","Runoob","Taobao","Facebook") function disp(arr_sites:string[]) { for(var i = 0;i<arr_sites.length;i++) { console.log(arr_sites[i]) } } disp(sites);编译以上代码,得到以下 JavaScript 代码:JavaScriptvar sites = new Array("Google", "Runoob", "Taobao", "Facebook");function disp(arr_sites) { for (var i = 0; i < arr_sites.length; i++) { console.log(arr_sites[i]); }}disp(sites);输出结果为:GoogleRunoobTaobaoFacebook作为函数的返回值TypeScriptfunction disp():string[] { return new Array("Google", "Runoob", "Taobao", "Facebook");} var sites:string[] = disp() for(var i in sites) { console.log(sites[i]) }编译以上代码,得到以下 JavaScript 代码:JavaScriptfunction disp() { return new Array("Google", "Runoob", "Taobao", "Facebook");}var sites = disp();for (var i in sites) { console.log(sites[i]);}输出结果为:GoogleRunoobTaobaoFacebook
-
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。元组中允许存储不同类型的元素,元组可以作为参数传递给函数。创建元组的语法格式如下:var tuple_name = [value1,value2,value3,…value n]实例声明一个元组并初始化:var mytuple = [10,"Runoob"];或者我们可以先声明一个空元组,然后再初始化:var mytuple = []; mytuple[0] = 120 mytuple[1] = 234访问元组元组中元素使用索引来访问,第一个元素的索引值为 0,第二个为 1,以此类推第 n 个为 n-1,语法格式如下:tuple_name[index]实例以下实例定义了元组,包含了数字和字符串两种类型的元素:TypeScriptvar mytuple = [10,"Runoob"]; // 创建元组console.log(mytuple[0]) console.log(mytuple[1])编译以上代码,得到以下 JavaScript 代码:JavaScriptvar mytuple = [10, "Runoob"]; // 创建元组console.log(mytuple[0]);console.log(mytuple[1]);输出结果为:10Runoob元组运算我们可以使用以下两个函数向元组添加新元素或者删除元素:push() 向元组添加元素,添加在最后面。pop() 从元组中移除元素(最后一个),并返回移除的元素。TypeScriptvar mytuple = [10,"Hello","World","typeScript"]; console.log("添加前元素个数:"+mytuple.length) // 返回元组的大小 mytuple.push(12) // 添加到元组中console.log("添加后元素个数:"+mytuple.length) console.log("删除前元素个数:"+mytuple.length) console.log(mytuple.pop()+" 元素从元组中删除") // 删除并返回删除的元素 console.log("删除后元素个数:"+mytuple.length)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar mytuple = [10, "Hello", "World", "typeScript"];console.log("添加前元素个数:" + mytuple.length); // 返回元组的大小mytuple.push(12); // 添加到元组中console.log("添加后元素个数:" + mytuple.length);console.log("删除前元素个数:" + mytuple.length);console.log(mytuple.pop() + " 元素从元组中删除"); // 删除并返回删除的元素console.log("删除后元素个数:" + mytuple.length);输出结果为:添加前元素个数:4添加后元素个数:5删除前元素个数:512 元素从元组中删除删除后元素个数:4更新元组元组是可变的,这意味着我们可以对元组进行更新操作:TypeScriptvar mytuple = [10, "Runoob", "Taobao", "Google"]; // 创建一个元组console.log("元组的第一个元素为:" + mytuple[0]) // 更新元组元素mytuple[0] = 121 console.log("元组中的第一个元素更新为:"+ mytuple[0])编译以上代码,得到以下 JavaScript 代码:JavaScriptvar mytuple = [10, "Runoob", "Taobao", "Google"]; // 创建一个元组console.log("元组的第一个元素为:" + mytuple[0]);// 更新元组元素mytuple[0] = 121;console.log("元组中的第一个元素更新为:" + mytuple[0]);输出结果为:元组的第一个元素为:10元组中的第一个元素更新为:121解构元组我们也可以把元组元素赋值给变量,如下所示:TypeScriptvar a =[10,"Runoob"] var [b,c] = a console.log( b ) console.log( c )编译以上代码,得到以下 JavaScript 代码:JavaScriptvar a = [10, "Runoob"];var b = a[0], c = a[1];console.log(b);console.log(c);输出结果为:10Runoob
-
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。元组中允许存储不同类型的元素,元组可以作为参数传递给函数。创建元组的语法格式如下:var tuple_name = [value1,value2,value3,…value n]实例声明一个元组并初始化:var mytuple = [10,"Runoob"];或者我们可以先声明一个空元组,然后再初始化:var mytuple = []; mytuple[0] = 120 mytuple[1] = 234访问元组元组中元素使用索引来访问,第一个元素的索引值为 0,第二个为 1,以此类推第 n 个为 n-1,语法格式如下:tuple_name[index]实例以下实例定义了元组,包含了数字和字符串两种类型的元素:TypeScriptvar mytuple = [10,"Runoob"]; // 创建元组console.log(mytuple[0]) console.log(mytuple[1])编译以上代码,得到以下 JavaScript 代码:JavaScriptvar mytuple = [10, "Runoob"]; // 创建元组console.log(mytuple[0]);console.log(mytuple[1]);输出结果为:10Runoob元组运算我们可以使用以下两个函数向元组添加新元素或者删除元素:push() 向元组添加元素,添加在最后面。pop() 从元组中移除元素(最后一个),并返回移除的元素。TypeScriptvar mytuple = [10,"Hello","World","typeScript"]; console.log("添加前元素个数:"+mytuple.length) // 返回元组的大小 mytuple.push(12) // 添加到元组中console.log("添加后元素个数:"+mytuple.length) console.log("删除前元素个数:"+mytuple.length) console.log(mytuple.pop()+" 元素从元组中删除") // 删除并返回删除的元素 console.log("删除后元素个数:"+mytuple.length)编译以上代码,得到以下 JavaScript 代码:JavaScriptvar mytuple = [10, "Hello", "World", "typeScript"];console.log("添加前元素个数:" + mytuple.length); // 返回元组的大小mytuple.push(12); // 添加到元组中console.log("添加后元素个数:" + mytuple.length);console.log("删除前元素个数:" + mytuple.length);console.log(mytuple.pop() + " 元素从元组中删除"); // 删除并返回删除的元素console.log("删除后元素个数:" + mytuple.length);输出结果为:添加前元素个数:4添加后元素个数:5删除前元素个数:512 元素从元组中删除删除后元素个数:4更新元组元组是可变的,这意味着我们可以对元组进行更新操作:TypeScriptvar mytuple = [10, "Runoob", "Taobao", "Google"]; // 创建一个元组console.log("元组的第一个元素为:" + mytuple[0]) // 更新元组元素mytuple[0] = 121 console.log("元组中的第一个元素更新为:"+ mytuple[0])编译以上代码,得到以下 JavaScript 代码:JavaScriptvar mytuple = [10, "Runoob", "Taobao", "Google"]; // 创建一个元组console.log("元组的第一个元素为:" + mytuple[0]);// 更新元组元素mytuple[0] = 121;console.log("元组中的第一个元素更新为:" + mytuple[0]);输出结果为:元组的第一个元素为:10元组中的第一个元素更新为:121解构元组我们也可以把元组元素赋值给变量,如下所示:TypeScriptvar a =[10,"Runoob"] var [b,c] = a console.log( b ) console.log( c )编译以上代码,得到以下 JavaScript 代码:JavaScriptvar a = [10, "Runoob"];var b = a[0], c = a[1];console.log(b);console.log(c);输出结果为:10Runoob
-
Any 类型任意值是 TypeScript 针对编程时类型不明确的变量使用的一种数据类型,它常用于以下三种情况。1、变量的值会动态改变时,比如来自用户的输入,任意值类型可以让这些变量跳过编译阶段的类型检查,示例代码如下:let x: any = 1; // 数字类型x = 'I am who I am'; // 字符串类型x = false; // 布尔类型改写现有代码时,任意值允许在编译时可选择地包含或移除类型检查,示例代码如下:let x: any = 4;x.ifItExists(); // 正确,ifItExists方法在运行时可能存在,但这里并不会检查x.toFixed(); // 正确定义存储各种类型数据的数组时,示例代码如下:let arrayList: any[] = [1, false, 'fine'];arrayList[1] = 100;Null 和 Undefinednull在 JavaScript 中 null 表示 "什么都没有"。null是一个只有一个值的特殊类型。表示一个空对象引用。用 typeof 检测 null 返回是 object。undefined在 JavaScript 中, undefined 是一个没有设置值的变量。typeof 一个没有值的变量会返回 undefined。Null 和 Undefined 是其他任何类型(包括 void)的子类型,可以赋值给其它类型,如数字类型,此时,赋值后的类型会变成 null 或 undefined。而在TypeScript中启用严格的空校验(--strictNullChecks)特性,就可以使得null 和 undefined 只能被赋值给 void 或本身对应的类型,示例代码如下:// 启用 --strictNullCheckslet x: number;x = 1; // 运行正确x = undefined; // 运行错误x = null; // 运行错误上面的例子中变量 x 只能是数字类型。如果一个类型可能出现 null 或 undefined, 可以用 | 来支持多种类型,示例代码如下:// 启用 --strictNullCheckslet x: number | null | undefined;x = 1; // 运行正确x = undefined; // 运行正确x = null; // 运行正确更多内容可以查看:JavaScript typeof, null, 和 undefinednever 类型never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。这意味着声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环),示例代码如下:let x: never;let y: number;// 运行错误,数字类型不能转为 never 类型x = 123;// 运行正确,never 类型可以赋值给 never类型x = (()=>{ throw new Error('exception')})();// 运行正确,never 类型可以赋值给 数字类型y = (()=>{ throw new Error('exception')})();// 返回值为 never 的函数可以是抛出异常的情况function error(message: string): never { throw new Error(message);}// 返回值为 never 的函数可以是无法被执行到的终止点的情况function loop(): never { while (true) {}}
-
ADC项目开发的代码用JS(typescript)语言编写吗?
-
设计模式是解决问题的良好模板,开发人员可以在自己的项目应用这些模式处理需求。现实中应付各种需求的模式数不胜数,一篇文章无法尽述。不过它们可以大致分为三个类别:结构模式,负责处理不同组件(或类)之间的关系,并形成新结构以提供新功能。结构模式的例子有组合(Composite)、适配器(Adapter)和装饰器(Decorator)。行为模式,它们能将组件之间的通用行为抽象为一个单独的实体,进而与你的创建模式结合起来。行为模式的例子包括命令(Command)、策略(Strategy)以及我个人最喜欢的一种:观察者(Observer)模式。创建模式,它们专注于类的实例化,简化新实体的创建过程,例如工厂(Factory)方法、单例(Singleton)和抽象工厂(Abstract Factory)。虽然它们可以直接在 JavaScript 中实现,特别是有了 ES6 后实现起来更容易了,但 TypeScript 采用的 OOP 方法使得开发人员可以简单明了地遵循通用指南(甚至来自其他 OOP 语言),从而获得这些模式的所有好处(而标准 JS 相比之下多少存在一些限制)。点击阅读全文
-
请问下we码vue模板可支持typescript吗?
-
请问下we码vue版本可支持typescript吗?
-
转自:CSDN 作者 :Md Kamaruzzaman,软件架构师原文地址:https://blog.csdn.net/FL63Zv9Zou86950w/article/details/104890017TypeScriptJavaScript是一门优秀的编程语言,在2015年之前,JavaScript有很多缺点。著名的软件工程师Douglas Crockford写了一本书名为《JavaScript: The Good Parts》,暗示了JavaScript有很糟的部分。无模块化,还有“回调地狱”,因此开发人员都不喜欢维护特别大的JavaScript项目。Google甚至还开发了一个平台,可将Java代码反编译为JavaScript代码(GWT)。许多公司和个人都曾尝试开发更好的JavaScript,例如CoffeeScript、Flow、ClojureScript。最终,微软的TypeScript取得了成功。微软的一队工程师在著名的Anders Hejlsberg的带领下,创建了JavaScript的静态类型、模块化超集——TypeScript。TypeScript可以编译为JavaScript。于2014年首次发布后,TypeScript很快引起了社区的关注。Google当时还计划开发JavaScript的静态类型超集。Google对TypeScript青睐有加,以至于他们没有开发新的语言,而是选择与微软合作改进TypeScript。Google选择TypeScript作为其SPA框架Angular 2+的主要编程语言。此外,流行的SPA框架React也提供对TypeScript的支持。另一个流行的JavaScript框架Vue.js也宣布将使用TypeScript开发新的Vue.js 3:另外,node.js的创建者Ryan Dahl已决定使用TypeScript来开发安全的Node.js替代品Deno。主要特征:与Go或Kotlin同样,TypeScript的主要特征也是语言设计。TypeScript凭借其简洁明快的代码,成为了目前最优雅的编程语言之一。就开发人员的生产力而言,它与JVM或Go/Python上的Kotlin并驾齐驱。TypeScript是生产力最高的JavaScript超集。TypeScript是JavaScript的强类型超集,特别适合大型项目,而且可以称为“可扩展的JavaScript”。单页应用程序框架的“三巨头”(Angular、React、Vue.js)为TypeScript提供了出色的支持。在Angular中,TypeScript是首选的编程语言。在React和Vue.js中,TypeScript越来越受欢迎。最大的两家技术巨头:微软和Google正在合作开发由活跃的开源社区支持的TypeScript。因此,TypeScript拥有最好的工具支持。由于TypeScript是JavaScript的超集,因此凡是可以运行JavaScript的任何地方都可以运行TypeScript,包括浏览器、服务器、移动设备、物联网设备和云。流行度:开发人员喜欢TypeScript的优雅语言设计。在StackOverFlow最受欢迎的语言类别的调查中,TypeScript与Python并列第二名:根据GitHub的排名,TypeScript是增长最快的编程语言之一,排名第五:从GitHub的贡献度来看,TypeScript排名第七,打进了前十:Google的趋势表明,在过去的几年中,TypeScript的热度越来越高:主要用途:Web UI开发服务器端开发主要竞争对手:JavaScriptDartSwift当初乔布斯拒绝在iOS中支持Java(和JVM),他认为Java不再是主流编程语言。如今我们发现乔布斯当初的估计是错的,虽然iOS仍然不支持Java。苹果选择了Objective-C作为iOS中的首选编程语言。Objective-C是一门很难掌握的语言,它不支持现代编程语言所要求的高生产力。后来,苹果的Chris Lattner和其他人开发了一种多范例、通用的、编译编程语言——Swift,来替代Objective-C。Swift的第一个稳定版本于2014年发布。Swift还支持LLVM编译器工具链(也由Chris Lattner开发)。Swift与Objective-C代码库具有出色的互操作性,并且已确立为iOS应用开发中的主要编程语言。主要特征:Swift的杀手级功能之一是其语言设计。语言本身很简单,语法简洁,比Objective-C更高效。Swift还提供了现代程序语言的功能:null安全。此外,它还提供了语法糖来避免“厄运金字塔”。作为一种编译语言,Swift和C++一样快。Swift支持LLVM编译器工具链。因此,我们可以在服务器端编程,甚至浏览器编程(使用WebAssembly)中使用Swift。Swift提供了自动引用计数(ARC)支持,可抑制内存管理的不善。流行度:开发人员对Swift的喜爱不亚于许多其他现代编程语言。根据StackOverflow的调查,Swift在最受欢迎的编程语言中排名第六:2019年,在TIOBE的编程语言排名中,Swift的排名上升到了第10名。鉴于这种编程语言只有5年的历史,可以说是成绩斐然:Google的趋势表明,在过去的几年中,Swift的热度出现了激增:主要用途:iOS应用开发系统编程客户端开发(通过WebAssembly)主要竞争对手:Objective-CRustGoDartDart是Google出品的第二大编程语言。Google是Web和Android领域的巨头,因此Google在Web和应用领域开发自己的编程语言也不足为奇。在丹麦软件工程师Lars Bak(领导Chrome的 JavaScript V8引擎开发)的带领下,Google于2013年发布了Dart。Dart是一种通用编程语言,支持“强类型”和“面向对象”编程。Dart也可以转编译为JavaScript,凡是JavaScript可以运行的任何地方(例如Web、移动、服务器)几乎都可以运行 Dart。主要特征:与Go一样,Dart也非常注重开发人员的工作效率。由于Dart简洁的语法,以及高效的生产力,受到开发人员的喜爱。Dart还提供“强类型”和“面向对象”编程。Dart是少数同时支持JIT编译(运行时编译)和AOT编译(创建时编译)的编程语言之一。因此,Dart可以针对JavaScript运行时(V8引擎),并且Dart可以编译为快速的原生代码(AOT编译)。跨平台原生应用程序开发平台Flutter选择了Dart作为开发iOS和Android应用的编程语言。从那以后,Dart的流行度越来越高。与Goog的Go编程语言一样,Dart也具有出色的工具支持和庞大的Flutter生态系统。Flutter的日益普及也会推动Dart的采用率升高。流行度:根据GitHub Octoverse数据显示,Dart是2019年增长最快的编程语言,去年它的流行度增长了五倍:根据TIOBE指数显示,Dart排名第23,仅用了4年时间就超过了很多其他的现代编程语言:根据StackOverflow的调查,Dart在最受欢迎的编程语言中排名第12:受Flutter的影响,Google的趋势表明,在过去的两年中,Dart的热度急剧上升:主要用途:应用开发UI开发主要竞争对手:JavaScriptTypeScriptJulia本文提及的大多数编程语言都是由大型公司开发的,但Julia是个例外。科技计算领域通常都会使用动态语言,例如Python、Matlab。虽然这些语言提供易于使用的语法,但不适用于大规模的科技计算。他们需要使用C/C ++库执行CPU密集型任务,因此这就产生了著名的“两种语言”的问题,因为他们需要粘合代码来绑定两种语言。由于编写的代码需要在两种语言之间来回切换,因此总是会损失部分性能。为了解决这个问题,麻省理工学院的一队研究人员计划从头开始创建一种新的语言,这种语言既可以利用现代硬件的优势,而且还结合其他语言的优势。于是,Julia诞生了。Julia是一种动态的高级编程语言,提供一流的并发、并行和分布式计算支持。Julia的第一个稳定版本于2018年发布,并很快受到社区和行业的关注。Julia可用于科学计算、人工智能和许多其他领域,而且还可以解决“两种语言”的问题。主要特征:与Rust一样,Julia的主要特征在于语言的设计。这种语言在不牺牲性能的情况下,将高性能和科学计算中现有编程语言的一些功能结合在一起。就目前的情况来看,Julia出色地完成了这项任务。Julia是一种动态编程语言,支持类型系统但类型不是必须的。因此,Julia这种编程语言很容易学习,生产力很高。Julia的核心是多调度编程范例。Julia内部支持并发、并行和分布式计算。Julia为I/O密集型任务提供异步I/O。Julia的运行速度非常快,可用于需要数百万个线程的科学计算。流行度:Julia在许多领域主要与Python竞争。由于Python是最流行的编程语言之一,因此Julia想晋升主流还需要几年的时间。虽然Julia非常新(只有一岁),但仍在TIOBE指数中排到第43名:Google趋势显示,在过去的一年中,Julia的热度在稳步增长:但是考虑到Julia的功能集,以及NSF、DARPA、NASA、因特尔等公司的推动,相信Julia取得突破的进展只是时间的问题。主要用途:科学计算高性能计算数据科学可视化主要竞争对手:PythonMatlab
-
摘选自作者Klint Finley在WIRED网站上发布的文章:TypeScript’s Quiet, Steady Rise Among Programming Languages最近一段时间,微软支持的编程语言在开发者中最受欢迎的语言排名中再次跃升。据分析公司RedMonk2019年3月发布的一份报告称,微软的编程语言TypeScript已经成为开发者中最流行的语言之一。TypeScript从第16位跃升到第12位,在RedMonk的半年度排名中仅次于苹果的编程语言Swift。微软在2012年发布了TypeScript,虽然它的增长速度没有Swift快,Swift从RedMonk在2011年开始编制排名以来,增长速度就比其他语言要快。但TypeScript的自身优势令人印象深刻,因为有大量可用的编程语言。现在越来越多的应用程序使用TypeScript。Google的编程框架Angular是用TypeScript编写的,根据去年NPM发布的数据,Angular是同类软件中第二流行的工具。Vue也是一个越来越受欢迎的框架,它在小公司和阿里巴巴这样的科技巨头中都找到了归宿。但是RedMonk没有考虑有多少职位适合精通某种语言的人,也没有考虑有多少公司实际使用这种语言。相反,该公司试图通过查看GitHub上有多少项目使用某些语言,以及在程序员问答网站Stack Overflow中有多少关于这些语言的问题来发现开发人员兴趣的趋势。其目的是了解软件开发行业的发展方向。TypeScript本质上是JavaScript的一种变体,JS一直是RedMonk排名中最流行的语言。实际上,所有的web应用程序在浏览器端都至少使用了一点JavaScript,而现在许多应用程序在服务器端也使用这种语言。JavaScript也用于移动和桌面应用程序。尽管自1995年首次引入以来,这种语言已经发生了很大的变化,但它最初并不是作为构建复杂应用程序的语言而设计的。TypeScript试图通过添加一些特别设计的功能来解决这个问题,这些功能使构建更大的项目变得更容易,例如微软的桌面代码编辑器VS代码,就是用这种语言编写的。TypeScript代码可以被翻译成JavaScript代码,或者用程序员的行话“编译”成JavaScript代码,这样它就可以在浏览器或者JavaScript运行的任何地方运行。得到科技巨头的支持,也促进了TypeScript的稳步上升。(微软已经发布了许多编程语言,最著名的是C#,在RedMonk的排名中排名第五)。但微软并不是唯一一家试图解决TypeScript产生的问题的公司。谷歌在2011年发布了一种名为Dart的编程语言,该语言也有类似的目标。TypeScript比Dart更成功,部分原因是不像Google的语言有自己的语法,TypeScript使用JavaScript的现有语法,使得已经知道JavaScript的程序员更容易学习TypeScript。
-
1 引言:面向对象好 现在有个充话费的需求,对于你是面向过程的。你需要执行种种流程:下载支付宝App,绑定银行卡,去网上营业厅买充值卡,充值到账。而对于你的女朋友,就大不一样了,是面向对象的。她会想:谁会充话费呢?当然是对象啦,她就跟你打电话,然后你把之前种种流程做了一遍,她收到到账短信说“谢谢亲爱的,么么哒”,这就是面向对象!女性思维大部分是面向对象的,她不关心种种流程和细节,她只关心谁可以,和结果。2 类与对象:一切皆对象 回到一个古老的话题:程序是什么? 程序=数据结构+算法 在面向对象编程(Object Oriented Programming, OOP)世界里,一切皆对象。面向对象程序=以对象为最小单位的数据结构+基于对象的操作算法类表示一类事物,而对象表示一个具体的事物。例如:学生是类,而李雷和韩梅梅都是对象。class Student {//学生类 constructor(public name:string){ }}let li: Student = new Student("Li Lei");// 李雷对象let han: Student = new Student("Han Meimei");//韩梅梅对象3 OOP三大特征3.1 封装:你办事,我放心。我不知道你内部如何运作。类是属性和方法的集合,封装就是对外暴露可操作的属性和方法,隐藏其他实现细节。属性描述同一类事物的特征,方法描述同一类事物的操作。例如:下面Animal类,对外暴露可读写的name/age/totalNum成员属性和可调用的eat()/sleep()/say()成员方法。后面还有一些例子中private属性和方法,是不对外暴露的隐藏属性和方法。抽象类含有未实现的抽象方法,等待子类去实现,所以不能实例化。例如:抽象类Animal含有未实现的抽象方法say(),。静态属性和静态方法是类所有,并不是每个对象所有,是全局性的属性和方法。例如:静态成员变量totalNum是类所有,记录已实例化动物总数。//抽象类abstract class Animal { public static totalNum = 0; //静态成员 constructor(public name: string, public age: number) {//转化为成员变量语法糖 Animal.totalNum++; }; public eat() { console.log("I am eating someting"); } public sleep() { console.log("I am sleeping"); } public abstract say();}测试用例:// let animal: Animal = new Animal("Error",10);//编译报错:无法创建抽象类。3.2 继承:龙生龙,凤生凤,老鼠的儿子会打洞子类继承了父类所有的属性和方法,并可以拥有自己新的属性和方法。继承解决了代码重用的问题。例如:Dog类继承了Animal类,拥有了Animal类所有的属性和方法name//age/sleep()/eat() /say()。并且可以覆盖和扩展,eat() /say()覆盖了父类的方法实现, wagtail()是扩展出父类没有的新方法。private/protected/public关键字,限定了对外可见范围。private只能在类内部访问;protected只能在类和子类内部访问;默认public,在类内部外部都能访问。 class Dog extends Animal { private shoutNum: number = 3; public eat() {//多态 覆盖原方法 console.log("I am eating meat"); } private getShoutSting(): string{ let shoutString: string=''; for(let i=0;i shoutString+="Wong!"; } return shoutString; } public say() { console.log(this.getShoutSting()); } public wagTail() {//扩展新方法 //... }}测试用例:let myDog: Animal = new Dog("DaHuang", 5); myDog.sleep();//I am sleeping myDog.eat();//I am eating meat myDog.say(); //Wong!Wong!Wong! // myDog.getShoutSting();//编译错误3.3 多态:我就是我,不一样的烟火 多态是指同一个方法在子类中具有不同表现形式。例如:Dog类和Cat类都有eat ()/say ()方法,尽管都是来自Animal定义的eat ()/say ()方法,但运行结果完全不同。class Cat extends Animal { public eat() {//多态 扩展原方法 super.eat(); console.log("I like eating fish"); } public say() { console.log("Miao~"); } public catchMouse() { //... }}测试用例:let myCat: Animal = new Cat("XiaoHua", 3); myCat.eat();//I am eating someting I like eating fish myCat.say();//Miao~4 接口4.1 接口:没有规矩不成方圆接口即规范,规定了某种能力必须要实现的方法。例如:Flyable接口规定了具有飞行能力必须实现fly()方法。Bird和Plane类都实现了Flyable接口,具有飞行能力。inte**ce Flyable { fly();}inte**ce catchBug { catchBug();}class Bird extends Animal implements Flyable,catchBug { public say() { console.log("Ji~Ji~Zha~Zha~"); } public fly() { console.log("I am flying with flapping my wings"); } public catchBug() { //... }}class Plane implements Flyable { fly() { console.log("I am flying with my engines"); } takePeople() { //... }}测试用例:let flyable1: Flyable = new Bird("Polly", 1); flyable1.fly(); //I am flying with flapping my wings // flyable1.eat();//编译报错: 不存在eat() let flyable2: Flyable = new Plane(); flyable2.fly();//I am flying with my engines4.2 抽象类与接口:有同有异抽象类和接口很类似,都有未实现的方法,等待其他类去实现。区别是:抽象类可以有一些成员的实现,而接口没有成员的实现;一个类只能继承自一个抽象类,但可以实现多个接口。例如:Animal类,有抽象方法say(),也有已实现的方法;上面Bird类只能继承自一个类,但又同时实现了flyable()/catchBug()两个接口。5 OOP设计原则5.1 李氏替换原则:父债可以子来偿所有引用基类的地方必须能透明的使用其子类的对象,因为子类的对象具有基类所有的属性和方法。(注:基类是指父类/父类的父类等)但反过来就不行了,有需要子类的地方,基类未必就能适应。例如:上面代码中,我们可以将Dog对象和Cat对象赋值给了Animal类型的变量。下面代码中,People构造函数需要一个Animal类型的参数,我们传入了Dog类型的对象。class People extends Animal{ constructor(public name: string, public age: number,public pet: Animal) { super(name,age); }; public say(){ console.log(`My name is ${this.name}, I am ${this.age} years old, my pet's name is ${this.pet.name}`); }}测试用例:let myBrother: People = new People("XiaoMing", 18, new Dog("GouDan", 2)); myBrother.say();//My name is XiaoMing, I am 12 years old, my pet's name is GouDan console.log('totalNum='+Animal.totalNum);//totalNum=5 //Dog/Cat/Bird/Dog/People/5.2 依赖倒置原则:面向接口编程,大家都依赖接口在无接口的代码组织中,是高层模块依赖低层模块。如果按照面向对象编程依赖倒置原则,高层模块和低层模块不互相依赖,他们都依赖于其接口/抽象类。例如:如果不存在接口,直接调用Bird类/Plane类的fly()方法,那么调用者便依赖于Bird类/Plane类。在上面例子中采用了接口编程,调用者的调用依赖于Flyable()接口;Bird类和Plane类的实现都依赖于Flyable()接口。请看下图,原本高层模块向下依赖的箭头,变为低层模块向上依赖的箭头。这就是依赖倒置名称的由来。无接口:有接口,依赖倒置:5.3 其他设计原则单一职责、开闭原则、接口隔离、迪米特法则等其他OOP设计原则呢,后会有期。6 总结在一切皆对象的世界中,我们已经学习了面向对象三大特征——封装、继承、多态,和两条面向对象设计原则——李氏替换原则、依赖倒置原则。后面有机会再介绍其他OOP设计原则和GoF设计模式。
-
1 引言:面向对象好 现在有个充话费的需求,对于你是面向过程的。你需要执行种种流程:下载支付宝App,绑定银行卡,去网上营业厅买充值卡,充值到账。而对于你的女朋友,就大不一样了,是面向对象的。她会想:谁会充话费呢?当然是对象啦,她就跟你打电话,然后你把之前种种流程做了一遍,她收到到账短信说“谢谢亲爱的,么么哒”,这就是面向对象!女性思维大部分是面向对象的,她不关心种种流程和细节,她只关心谁可以,和结果。2 类与对象:一切皆对象 回到一个古老的话题:程序是什么? 程序=数据结构+算法 在面向对象编程(Object Oriented Programming, OOP)世界里,一切皆对象。面向对象程序=以对象为最小单位的数据结构+基于对象的操作算法类表示一类事物,而对象表示一个具体的事物。例如:学生是类,而李雷和韩梅梅都是对象。class Student {//学生类 constructor(public name:string){ }}let li: Student = new Student("Li Lei");// 李雷对象let han: Student = new Student("Han Meimei");//韩梅梅对象3 OOP三大特征3.1 封装:你办事,我放心。我不知道你内部如何运作。类是属性和方法的集合,封装就是对外暴露可操作的属性和方法,隐藏其他实现细节。属性描述同一类事物的特征,方法描述同一类事物的操作。例如:下面Animal类,对外暴露可读写的name/age/totalNum成员属性和可调用的eat()/sleep()/say()成员方法。后面还有一些例子中private属性和方法,是不对外暴露的隐藏属性和方法。抽象类含有未实现的抽象方法,等待子类去实现,所以不能实例化。例如:抽象类Animal含有未实现的抽象方法say(),。静态属性和静态方法是类所有,并不是每个对象所有,是全局性的属性和方法。例如:静态成员变量totalNum是类所有,记录已实例化动物总数。//抽象类abstract class Animal { public static totalNum = 0; //静态成员 constructor(public name: string, public age: number) {//转化为成员变量语法糖 Animal.totalNum++; }; public eat() { console.log("I am eating someting"); } public sleep() { console.log("I am sleeping"); } public abstract say();}测试用例:// let animal: Animal = new Animal("Error",10);//编译报错:无法创建抽象类。3.2 继承:龙生龙,凤生凤,老鼠的儿子会打洞子类继承了父类所有的属性和方法,并可以拥有自己新的属性和方法。继承解决了代码重用的问题。例如:Dog类继承了Animal类,拥有了Animal类所有的属性和方法name//age/sleep()/eat() /say()。并且可以覆盖和扩展,eat() /say()覆盖了父类的方法实现, wagtail()是扩展出父类没有的新方法。private/protected/public关键字,限定了对外可见范围。private只能在类内部访问;protected只能在类和子类内部访问;默认public,在类内部外部都能访问。 class Dog extends Animal { private shoutNum: number = 3; public eat() {//多态 覆盖原方法 console.log("I am eating meat"); } private getShoutSting(): string{ let shoutString: string=''; for(let i=0;i shoutString+="Wong!"; } return shoutString; } public say() { console.log(this.getShoutSting()); } public wagTail() {//扩展新方法 //... }}测试用例:let myDog: Animal = new Dog("DaHuang", 5); myDog.sleep();//I am sleeping myDog.eat();//I am eating meat myDog.say(); //Wong!Wong!Wong! // myDog.getShoutSting();//编译错误3.3 多态:我就是我,不一样的烟火 多态是指同一个方法在子类中具有不同表现形式。例如:Dog类和Cat类都有eat ()/say ()方法,尽管都是来自Animal定义的eat ()/say ()方法,但运行结果完全不同。class Cat extends Animal { public eat() {//多态 扩展原方法 super.eat(); console.log("I like eating fish"); } public say() { console.log("Miao~"); } public catchMouse() { //... }}测试用例:let myCat: Animal = new Cat("XiaoHua", 3); myCat.eat();//I am eating someting I like eating fish myCat.say();//Miao~4 接口4.1 接口:没有规矩不成方圆接口即规范,规定了某种能力必须要实现的方法。例如:Flyable接口规定了具有飞行能力必须实现fly()方法。Bird和Plane类都实现了Flyable接口,具有飞行能力。inte**ce Flyable { fly();}inte**ce catchBug { catchBug();}class Bird extends Animal implements Flyable,catchBug { public say() { console.log("Ji~Ji~Zha~Zha~"); } public fly() { console.log("I am flying with flapping my wings"); } public catchBug() { //... }}class Plane implements Flyable { fly() { console.log("I am flying with my engines"); } takePeople() { //... }}测试用例:let flyable1: Flyable = new Bird("Polly", 1); flyable1.fly(); //I am flying with flapping my wings // flyable1.eat();//编译报错: 不存在eat() let flyable2: Flyable = new Plane(); flyable2.fly();//I am flying with my engines4.2 抽象类与接口:有同有异抽象类和接口很类似,都有未实现的方法,等待其他类去实现。区别是:抽象类可以有一些成员的实现,而接口没有成员的实现;一个类只能继承自一个抽象类,但可以实现多个接口。例如:Animal类,有抽象方法say(),也有已实现的方法;上面Bird类只能继承自一个类,但又同时实现了flyable()/catchBug()两个接口。5 OOP设计原则5.1 李氏替换原则:父债可以子来偿所有引用基类的地方必须能透明的使用其子类的对象,因为子类的对象具有基类所有的属性和方法。(注:基类是指父类/父类的父类等)但反过来就不行了,有需要子类的地方,基类未必就能适应。例如:上面代码中,我们可以将Dog对象和Cat对象赋值给了Animal类型的变量。下面代码中,People构造函数需要一个Animal类型的参数,我们传入了Dog类型的对象。class People extends Animal{ constructor(public name: string, public age: number,public pet: Animal) { super(name,age); }; public say(){ console.log(`My name is ${this.name}, I am ${this.age} years old, my pet's name is ${this.pet.name}`); }}测试用例:let myBrother: People = new People("XiaoMing", 18, new Dog("GouDan", 2)); myBrother.say();//My name is XiaoMing, I am 12 years old, my pet's name is GouDan console.log('totalNum='+Animal.totalNum);//totalNum=5 //Dog/Cat/Bird/Dog/People/5.2 依赖倒置原则:面向接口编程,大家都依赖接口在无接口的代码组织中,是高层模块依赖低层模块。如果按照面向对象编程依赖倒置原则,高层模块和低层模块不互相依赖,他们都依赖于其接口/抽象类。例如:如果不存在接口,直接调用Bird类/Plane类的fly()方法,那么调用者便依赖于Bird类/Plane类。在上面例子中采用了接口编程,调用者的调用依赖于Flyable()接口;Bird类和Plane类的实现都依赖于Flyable()接口。请看下图,原本高层模块向下依赖的箭头,变为低层模块向上依赖的箭头。这就是依赖倒置名称的由来。无接口:有接口,依赖倒置:5.3 其他设计原则单一职责、开闭原则、接口隔离、迪米特法则等其他OOP设计原则呢,后会有期。6 总结在一切皆对象的世界中,我们已经学习了面向对象三大特征——封装、继承、多态,和两条面向对象设计原则——李氏替换原则、依赖倒置原则。后面有机会再介绍其他OOP设计原则和GoF设计模式。
上滑加载中
推荐直播
-
全面解析华为云EI-API服务:理论基础与实践应用指南
2024/11/29 周五 18:20-20:20
Alex 华为云学堂技术讲师
本期直播给大家带来的是理论与实践结合的华为云EI-API的服务介绍。从“主要功能,应用场景,实践案例,调用流程”四个维度来深入解析“语音交互API,文字识别API,自然语言处理API,图像识别API及图像搜索API”五大场景下API服务,同时结合实验,来加深开发者对API服务理解。
回顾中 -
企业员工、应届毕业生、在读研究生共探项目实践
2024/12/02 周一 19:00-21:00
姚圣伟 在职软件工程师 昇腾社区优秀开发者 华为云云享专家 HCDG天津地区发起人
大神带你一键了解和掌握LeakyReLU自定义算子在ONNX网络中应用和优化技巧,在线分享如何入门,以及在工作中如何结合实际项目进行学习
即将直播 -
昇腾云服务ModelArts深度解析:理论基础与实践应用指南
2024/12/03 周二 14:30-16:30
Alex 华为云学堂技术讲师
如何快速创建和部署模型,管理全周期AI工作流呢?本期直播聚焦华为昇腾云服务ModelArts一站式AI开发平台功能介绍,同时结合基于ModelArts 的实践性实验,帮助开发者从理论到实验更好地理解和使用ModelArts。
去报名
热门标签