OOP面向对象 ----三大特征 继承封装多态
面向对象(Object Oriented,OO)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术[1] 发展到一定阶段后的产物。
三大特性:继承,封装,多态
封装:使用访问控制符可以将对象中不允许外部程序直接访问的重要属性隐藏在对象内部,这一过程叫封装。封装减少了大量的冗余代码,封装将复杂的功能封装起来,对外开放一个接口,将描述事物的数据和操作封装在一起,形成一个类;被封装的数据和操作只有通过提供的公共方法才能被外界访问(封装隐藏了对象的属性和实施细节),私有属性和方法是无法被访问的,表现了封装的隐藏性,增加数据的安全性。
个人理解来说: 封装分两类,方法的封装和属性的封装,分别将类方法和类属性私有化,进而限制访问,注意!!并不是拒绝访问,而是限制访问 。
方法私有化之后,在类外部无法使用,属性私有化之后,需要使用设置和读取私有属性的get/set的方法,外部才能使用
然后啥叫私有方法私有属性呢?
白话来说,在构造函数中,使用var生命的变量叫做私有属性,使用function声明的方法就叫做私有方法 (记住)私有属性和私有方法只在构造函数中有效啊,这点很重要啊 (你要是问我啥叫构造函数的话,emmmm自己百度好不好呀)
结果如图:
继承 被继承的类叫做父类,继承父类的类叫做子类,继承中子类将会获得父类的属性和方法,同时子类也可以定义自己的属性和方法,继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用 基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力。
js实现继承是通过 apply方法或者是通过prototype实现的,如果使用apply方法,子类的原型是子类,如果使用prototype,那么子类的原型也将继承父类。
/** * 点击查询 * @author gongliying * @date 2019-06-03 */ search(val) { function fatherClass(name,age){ this.name = name; this.age = age; this.say = function(){ console.log(" the say method of father class"); } } function oneSon(name,age){ fatherClass.apply(this,[name,age]); } var objOneSon = new oneSon("oneSon",20); console.log(objOneSon.name,'这是name'); console.log(objOneSon.age,'这是age'); objOneSon.say(); //instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置 console.log(objOneSon instanceof fatherClass,'是否出现在父类'); console.log(objOneSon instanceof oneSon,'是否出现在子类'); },
结果为
如果使用prototype方法
以上方法不变
//加入prototype
oneSon.prototype = new fatherClass(); var objOneSon = new oneSon("oneSon",20); console.log(objOneSon.name,'这是name');
console.log(objOneSon.age,'这是age'); objOneSon.say(); //instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置 console.log(objOneSon instanceof fatherClass,'是否出现在父类'); console.log(objOneSon instanceof oneSon,'是否出现在子类');
结果如右图
此外 还有一个就是咱么ES6上面的了 extends 他的实质呢 就是说先创造实例对象this,然后再 子类继承的时候修改父类this 重新写个例子~~ (夸赞的话请忽略~~~)
/** * oopES6 extend 继承实现 * @author gongliying * @data 2019-06-10 */ class gong{ //构造函数 constructor(props) { this.name = props.name } age() { console.log(this.name + "今年18岁~~"); } } class zhang extends gong { //构造函数 constructor(props) { //调用实现父类的构造函数 super(props); this.type = props.type; } character() { console.log(this.name + "是个温柔的女孩子~~"); } } var Gong = new zhang({ name :'丽颖' })
//结果为 Gong.age() --------------------//丽颖今年18岁~~ Gong.character() ---------------//丽颖是个温柔的女孩子~~
多态 是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。子类的方法会覆盖父类的方法,即表现的就是多态性
/** * 点击查询 * @author gongliying * @date 2019-06-03 */ search(val) { function fatherClass(name,age){ this.name = name; this.age = age; this.say = function(){ console.log(" the say method of father class"); } } function anotherSon(name,age){ this.say = function(){ console.log("i am anotherSon"); } } anotherSon.prototype = new fatherClass(); function twoSon(name,age){ this.say = function(){ console.log("i am twoSon"); } } twoSon.prototype = new fatherClass(); function yes_or_no(cls){ if(cls instanceof fatherClass){ cls.say(); } } var objanotherSon = new anotherSon(); var objtwoSon = new twoSon(); yes_or_no(objanotherSon); yes_or_no(objtwoSon); },
结果为 即实现了类的多态
多态的主要体现在重写和重载 但是何为重写重载呢?
重写:子类定义了与父类相同的方法,并且有相同的参数类型和参数个数
重载:具有不同参数列表的同名方法,参数的类型或者参数的个数不同,方法的返回值可以相同也可以不相同
我理解的重写和重载就是 --- 重写: 改变方法的实现方式,发生在继承类中,但是被重写的方法不能拥有更严格的权限即子类的访问权限>父类的访问权限 重载:好多种方式,就是说参数不同 但是发生在一个类中并且对权限没有要求
(emmmmm重写重载这么直白的区别就不需要我说了把-_- ~~)
重写:
子类继承父类时,将相同的方法重写
/** * oop 多态重写实现 * @author gongliying * @data 2019-06-10 */ aaa(){ class gong{ //构造函数 constructor(props) { this.name = props.name } age() { console.log(this.name + "今年18岁~~"); } } class zhang extends gong { //构造函数 constructor(props) { //调用实现父类的构造函数 super(props); this.type = props.type; } age() { console.log(this.name + "是个温柔的女孩子~~"); } } var Gong = new zhang({ name :'丽颖' }) Gong.age() -----------------//丽颖是个温柔的女孩子~~ }
重载:
相同的方法,接收的参数类型不同,返回结果不同 但是 严格意义上说 JavaScript上并没有重载的概念,因为javaScript中的函数参数都保存在arguments对象中,重复定义相同名字的函数,后定义的会覆盖之前的。 但是我们可以模拟
/** * oop 多态重载实现 * @author gongliying * @data 2019-06-10 */ aaa(){ class gong{ constructor(content){ switch(typeof content){ case 'number': console.log('数字') break; case 'string': console.log('字符串') break; case 'boolean': console.log('布尔') break; } } } new gong(123) -----------------//数字 new gong('liying') ------------//字符串 new gong(false) ----------------//布尔 }
模拟完毕~~~
emmmmm,这是我目前的所有理解了 ,以后还有更生层次的理解会更新的,敬请期待哟~~~~
写的不好多多见谅,欢迎评价~~~~中国特色社会主义式可爱~~~~