面向对象简介、类的简介、属性、方法、构造函数、封装、多态、继承——JS面向对象

28 篇文章 0 订阅
21 篇文章 2 订阅

目录

一、面向对象简介

二、类的简介

三、属性

四、方法

五、构造函数(constructor)

六、封装

七、多态

八、继承

一、面向对象简介

面向对象编程(OOP)

        1. 程序是干嘛的?

                - 程序就是对现实世界的抽象

        2. 对象是干嘛的?

                - 一个事物抽象到程序中后就变成了对象

                - 在程序的世界中,一切皆对象

        3. 面向对象的编程

                - 面向对象的编程指程序中的所有操作都是通过对象来完成的

                - 做任何事之前都需要先找到它的对象

- 一个事物通常由两部分组成:数据和功能

- 一个对象由两部分组成:属性和方法

- 事物的数据到了对象中,体现为属性

- 事物的功能到了对象中,体现为方法

	<script>
		const five = {
			//添加属性
			name:"王老五",
			age:48,
			height:180,
			weight:100,
			//添加方法
			sleep(){
				console.log(this.name + "睡觉了~~");
			},//注意对象的每个属性或方法应该应英文逗号隔开
			eat(){
				console.log(this.name + "吃饭了~~");
			}
		}
		console.log(five.name)
		five.sleep()
	</script>

二、类的简介

使用 Object 创建对象的问题

        1. 无法区分出不同类型的对象

        2. 不方便批量创建对象

在JS中可以通过类(class)来解决这个问题:

        1. 类是创建对象的模板,可以将对象中的属性和方法直接定义在类中

                定义后,就可以直接通过类来创建对象

        2. 通过同一个类创建的对象,我们称为同类对象

                可以使用 instanceof 来检查一个对象是否由某个类创建

                如果某个对象是由某个类所创建,则我们称该对象是这个类的实例

                     语法:对象 instanceof 类名    若是则返回true,否则返回false

语法:

        class 类名{ }  //类名要使用大驼峰命名

        const 类名 = class { }

通过类创建对象:     new   类( )   //调用构造函数创建对象

	<script>
		//Preson类专门用来创建人的对象
		class Person{			
		}
		//Dog专门用来创建狗的对象
		class Dog{
		}
		const p1 = new Person()//调用构造函数创建对象
		const d1 = new Dog()
		console.log(p1)
		console.log(d1);
		console.log(p1 instanceof Person)//true	
	</script>

三、属性(实例属性和静态属性)

类是创建对象的模板,要创建第一件事就是定义类

类的代码块,默认就是严格模式,类的代码块是用来设置对象的属性的,不是什么代码都能写

实例属性:只能通过实例访问

静态属性(类属性):只能通过类访问,使用 static 声明的属性是类属性。

	<script>
		class Person{	
			name = "孙悟空"//Person的实例属性name
			age	= 18	//实例属性只能通过实例访问
			static test  = 'test静态属性'//使用static声明的属性,是静态属性(类属性)
										//静态属性只能通过类去访问Person.test 
		}		
		const p1 = new Person()//调用构造函数创建对象		
		console.log(p1)
	</script>

四、方法(实例方法和静态方法)

实例方法,实例方法中的this 就是当前实例

        方法名 (){ }

静态方法(类方法),通过类来调用,静态方法中this 指向的是当前类

        static 方法名(){ }

还可以使用  方法名 = function(){ } 添加方法,但一般不用。

	<script>
		class Person{	
			name = "孙悟空"//Person的实例属性name
			// sayHello = function(){

			// }//添加方法的一种方式
			sayHello(){
				console.log('大家好,我是'+this.name)
			}//添加方法(实例方法) 实例方法中this 就是当前实例
			static test(){
				console.log("我是静态方法")
			}//静态方法(类方法)通过类来调用,静态方法中this 指向的是当前类
		}		
		const p1 = new Person()//调用构造函数创建对象		
		console.log(p1)
		Person.test()//调用静态方法
	</script>

五、构造函数(constructor)

当我们在类中直接指定实例属性的值时,意味着我们所创建的对象的属性都是这个值

构造函数:

      在类中可以添加一个特殊的方法constructor(){ },该方法我们称为构造方法(构造函数)

构造函数会在我们调用类创建对象时执行

     可以在构造函数中,为实例属性进行赋值

     在构造函数中,this 表示当前所创建的对象

	<script>
		class Person{
			constructor(name,age,gender){
				//可以在构造函数中,为实例属性进行赋值
				//在构造函数中,this表示当前所创建的对象
				this.name = name//左边是对象的属性,右边是传入的参数
				this.age = age
				this.gender = gender
				console.log("构造函数执行了");
			}
		}
		const p1 = new Person("孙悟空",18,"男")
		console.log(p1)
	</script>

六、封装

面向对象的特点:封装、继承和多态。

封装 

       - 对象就是一个用来存储不同属性的容器

       - 对象不仅负责属性,还要负责数据的安全

       - 直接添加到对象中的属性,并不安全,因为他们可以被任意的修改

       - 如何确保数据的安全:

               1. 私有化数据(实例属性使用 # 开头就变成了私有属性,私有属性只能在类内部访问)

                  - 将需要保护的数据设置为私有,只能在类内部使用,不能直接

               2.提供 setter 和 getter 方法来开放对数据的操作

                 - getter 方法用来读取属性, setter 方法用来设置属性

                属性设置私有,通过getter , setter 方法操作属性带来的好处

                  1. 可以控制属性的读写权限(通过是否设置setter, getter方法控制)

                  2. 可以在方法中对属性的值进行验证

	<script>
		class Person{
			#address = "花果山"//实例使用# 开头就变成了私有属性,私有属性只能在类内部访问
			#name
			#age
			constructor(name,age,gender){
				this.#name = name//在构造函数中的私有属性要先在构造函数外部定义之后才能使用
				this.#age = age
				this.gender = gender
			}
			sayHello(){
				console.log(this.#name);
			}
			//getter方法,用来读取属性
			getName(){
				return this.#name
			}
			//setter方法,用来设置属性
			setName(name){
				this.#name = name
			}
			getAge(){
				return this.#age
			}
			setAge(age){
				//在方法中对属性的值进行验证
				if(age>=0){
					this.#age = age
				}			
			}
		}
		const p1 = new Person("孙悟空",18,"男")
		console.log(p1);
		// p1.#address//报错,私有属性无法访问
		console.log(p1.getName()); 
		p1.setName('猪八戒')
		console.log(p1);
	</script>

 封装主要用来保证数据的安全

实现封装的方式:

        1. 属性私有化,加#

        2. 通过getter 和 setter 方法来操作属性

                get 属性名(){

                       return this.#属性

                }

                set 属性名(参数){

                        this.#属性 = 参数

                }

        调用setter方法的话,为实例.属性名

        调用getter方法的话,为实例.属性名 = 参数,即与未私有化之前使用或修改属性一样

	<script>
		class Person{
			#address = "花果山"//实例使用# 开头就变成了私有属性,私有属性只能在类内部访问
			#name
			#age
			constructor(name,age,gender){
				this.#name = name
				this.#age = age
				this.gender = gender
			}
			//getter方法,用来读取属性
			get name(){
                console.log("getter执行了~")
				return this.#name
			}
			set name(name){
				this.#name = name
			}		
		}
		const p1 = new Person("孙悟空",18,"男")
		console.log(p1.name);//调用get方法
		p1.name = '猪八戒'	//调用set方法为其重新赋值	
		console.log(p1);
	</script>

七、多态

多态

        - 在JS中不会检查参数的类型,所以这就意味着任何数据都可以作为参数传递

        - 要调用某个函数,无需指定类型,只要对象满足某些条件即可

        - 程序中如何判断是否是鸭子:如果一个东西走路像鸭子,叫起来像鸭子,那么他就是鸭子

        - 多态为我们提供了灵活性

	<script>
		class Person{
			constructor(name){
				this.name = name
			}
		}
		class Dog{
			constructor(name){
				this.name = name
			}
		}
		const dog = new Dog("旺财")
		const person = new Person("孙悟空")
		console.log(dog)
		console.log(person)
		//定义一个函数,这个函数将接收一个对象作为参数,他可以输出hello并打印对象的name属性
		function sayHello(obj){
			// if(obj instanceof Person){
				console.log("hello",obj.name)
			// }		
		}
		sayHello(dog)//调用sayHello,只需满足含有name属性即可,既可以传人的类,也可以传狗的类
	</script>

八、继承

可以通过 extends 关键字来完成继承

当一个类继承另一个类时,就相当于将另一个类中的代码复制到了当前类中(简单理解)

继承发生时,被继承的类称为父类(超类),继承的类称为子类

通过继承可以减少重复的代码,并且可以在不修改一个类的前提对其进行扩展。

    封装——确保安全性

    继承——扩展性

    多态——灵活性

	<script>
		class Animal{
			constructor(name){
				this.name = name
			}
			sayHello(){
				console.log("动物在叫");
			}
		}
		class Dog extends Animal{
			
		}
		class Cat{
			constructor(name){
				this.name = name
			}
			sayHello(){
				console.log("喵喵喵");
			}
		}
		const dog = new Dog("旺财")
		const cat = new Cat("汤姆")
        console.log(dog)
		dog.sayHello()
		cat.sayHello()
	</script>

在子类中,可以通过创建同名方法重写父类的方法

重写构造函数时,构造函数的第一行代码必须为super(), 表调用父类的构造函数

   在方法中可以使用super来引用父类的方法,如super.sayHello()

构造函数用来创建对象,当重写构造函数时,就相当于父类的构造函数没了,这样就没有办法创建父类的实例

通过继承可以在不修改一个类的情况下对其进行扩展

OCP 开闭原则

     - 程序应该对修改关闭,对扩展开放

	<script>
		class Animal{
			constructor(name){
				this.name = name
			}
			sayHello(){
				console.log("动物在叫");
			}
		}
		class Dog extends Animal{
			//重写构造函数
			constructor(name){
				//重写构造函数时,构造函数的第一行代码必须为super()
				super(name)//调用父类的构造函数
			}
			sayHello(){
				//调用一下父类的sayHello
				super.sayHello()//在方法中可以使用super来引用父类的方法
				console.log("汪汪汪")
			}
		}
		class Cat extends Animal{			
			sayHello(){
				
				console.log("喵喵喵");
			}
		}
		const dog = new Dog("旺财")
		const cat = new Cat("汤姆")
		dog.sayHello()
		cat.sayHello()
		console.log(dog.name);
	</script>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值