携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
面向对象
- 把客观对象抽象成属性数据和数据的相关操作,吧内部的细节和不相关的数据隐藏起来
- 吧同一个类型的客观对象的属性和数据绑定到一起,封装成类。
- 并且允许分成不同的层次进行抽象,通过继承实现属性和操作的共享
- 面向对象的分析 OOA
- 面向对象的设计 OOD
- 面向对象的编程 OOP
概念
- 类、对象
- 父类是公共的
案例1
class Animal{
constructor(name){
this.name=name
}
eat(food){
console.log(`${this.name}吃${food}`)
}
}
let dog=new Animal('狗')
dog.eat()
案例2
class Animal{
constructor(name){
this.name=name
}
eat(food){
console.log(`${this.name}吃${food}`)
}
}
class Dog extends Animal{
constructor(name){
super(name)
}
speak(){
console.log("汪汪汪")
}
}
let dog=new Dog('狗')
dog.eat("骨头")
dog.speak()
案例3
class Animal{
constructor(name){
this.name=name
}
eat(food){
console.log(`${this.name}吃${food}`)
}
}
class Dog extends Animal{
constructor(name){
super(name)
}
speak(){
console.log("汪汪汪")
}
}
class Cat extends Animal{
constructor(name){
super(name)
}
speak(){
console.log("喵喵喵")
}
}
let dog=new Dog('狗')
dog.eat("骨头")
dog.speak()
let cat=new Cat('猫')
cat.eat("鱼")
cat.speak()
他们的共同属性放到父类里面,他们单独的属性放到子类里面
封装
封装的概念就是该给别人看的就给别人看,要么就只给自己看
- 将数据封装起来
- 减少耦合,不该外部访问的不要让外部访问
- 利于数据的接口权限管理
- 目前ES6不支持,一般认为_开头的都会私有,不要使用
- 实现
- public: 公有修饰符,可以在类内部或者在类的外部使用public修饰的属性或者行为。默认修饰符
- protected: 受保护的修饰符,可以在本类或者子类中使用protected修饰的属性和行为
- private:私有修饰符,只可以在类内部使用private修饰的属性和行为
javascript没有上面的玩意,所以我们要使用typescript
typescript安装方式
npm install -g typescript
这样我们就可以编译ts文件了,他的本质是吧ts文件编译成js文件。使用方式如下
tsc [你的文件名].ts
案例1
function greeting(user){
return 'hello'+user
}
let user='xxxx'
console.log(greeting(user))
编译后:
function greeting(user) {
return 'hello' + user;
}
var user = 'xxxx';
console.log(greeting(user));
使用typescript实现封装
class Person{
public name:string; // 公有属性,自己,自己的子类和其他类都能访问
protected age: number;// 受保护的属性 自己 自己的子类能访问,其他类不能访问
private money:number; // 私有的,自己能访问,自己的子类和其他类都不能访问
constructor(name,age,money){
this.name=name
this.age=age
this.money=money
}
}
class Student extends Person {
public num:number;
constructor(name,age,money,num){
super(name,age,money)
this.num=num
}
getName(){
console.log(`我的名字叫${this.name}`)
}
getAge(){
console.log(`我的年龄${this.age}`)
}
}
let s1=new Student('丁真',10,100,1)
console.log(s1.name)
这样我们就能够将数据给他很好的封装起来了。
多态
多态的本质是同一个接口可以有不同的实现,这样我们就能够实现面向接口编程。比如一个父类有两个子类,子类都能够重写父类的方法,这种情况叫做多态。
class Animal2 {
name: string;
constructor(name){
this.name=name
}
eat(food){
}
}
class Dog2 extends Animal2 {
eat(food: any): void {
console.log("狗狗吃"+food)
}
}
class Person2 extends Animal2{
eat(food: any): void {
console.log("人吃"+food)
}
}
let d=new Dog2('狗')
d.eat('肉')
let p=new Person2('人')
p.eat('饭')
但是最后还是要提一个特性,就是你在typescript里面,你约束了这个变量或者说数据的作用范围。但是你如果说在typescript文件编译过后的javascript文件里面直接访问这个被约束的变量,他还是可以拿到的。约束只是对typescript文件做约束,并没有考虑到编译之后的javascript,详情请看案例1
案例1
- 首先定义一个4.ts文件,代码如下:
class Test{
private name:string;
constructor(name){
this.name=name
}
}
let t=new Test('丁真')
- 编译成JavaScript
tsc 4.ts
- JavaScript代码如下:
var Test = /** @class */ (function () {
function Test(name) {
this.name = name;
}
return Test;
}());
var t = new Test('丁真');
- 尝试打印test对象的名字
var Test = /** @class */ (function () {
function Test(name) {
this.name = name;
}
return Test;
}());
var t = new Test('丁真');
console.log(t.name)
最后我们会发现,他还是能够正常吧test的名字打印出来. 这个是我感觉非常不好的。但是遗憾的是JavaScript就是这样。如果我们尝试在TypeScript里面打印test对象的名字,他就会给我们报错信息提示:
但是如果我们忽略typescript给出的警告,在typescript文件内非法的使用受限制的成员变量,我们还是能够正常编译typescript文件,但是他会给我们警告,并且在编译出来的JavaScript文件中也会和源文件有很大的不同。
案例2
- 新建一个typescript文件,编写代码:
class Person3{
private money:number;
}
let p=new Person3()
console.log(p.money)
- 编译这个typescript文件:
tsc [你的文件名].ts
- 编译出来的JavaScript文件:
var Person3 = /** @class */ (function () {
function Person3() {
}
return Person3;
}());
var p = new Person3();
console.log(p.money);
可以看到,我们定义的name在新生成的JavaScript文件中已经不存在了。这个就是TypeScript针对我们非法使用变量,并且还要强制编译,又为了实现我们的常规效果所作出的限制。
【前端设计模式01-面向对象】 到此结束,如果您觉得对您有帮助的话,可以点赞收藏一下哦。您的支持就是对我最大的鼓励,能让我得到更多的推送流量,帮助到更多的人,最后感谢您花费宝贵的时间认真的阅读这篇文章。如果说您有什么需要我改进的建议欢迎到评论区一起和我讨论❤❤❤。