day17面向对象

本文介绍了面向对象编程的核心概念,包括封装、继承和多态,并通过JavaScript示例解释了如何声明对象、创建类以及使用构造函数。文中还探讨了类与构造函数的区别,展示了对象创建的不同方式,如工厂函数,并提供了实际的代码示例来说明这些概念。
摘要由CSDN通过智能技术生成

面向对象概述(oop

面向对象是一种编程思维(oop),将对应的你需要用到的对象进行提取,将对应方法综合到对应的对

象中,在需要调用对应的方法的时候去找对应的对象。(万物皆对象(任何东西都可以抽取为对象),

主要的过程就是找对应的对象做对应的事情。)

示例

相亲 (面向过程)过程中会产生很多的行为(行为比较分散)

  • 找媒婆 (介绍人)

  • 提需求 (你)

  • 匹配人 (媒婆)

  • 见面

  • 相互了解

  • ....

面向对象(主要是找对应的对象 去做对应的事情(忽略过程))

  • 媒婆

  • 相亲对象

面向对象的核心就是找对象

面向对象的三大特性

  • 封装 (将对应的属性和方法抽取封装到对应的类(构造函数)中)

  • 继承(子类继承父类 子类拥有父类非私有属性及方法)

  • 多态(一个东西多种形态体(基于继承的) 重载(一个类多个函数重名(js中不允许的))重写(子类重写父类方法))

对象创建声明的方式

使用new关键词来声明 (实际调用的都是构造函数)

  • es6新增的class (其实调用也是构造函数)

class Person{
    //类的构造器
    constructor(name){
        this.name = name
    }
}
//调用类中的构造器
let person = new Person('jack')
  • es3自带的构造函数

function Person(name){
    this.name = name
}
let person = new Person('tom')

构造函数和class的区别

  • 构造函数的兼容会比class要好

  • 构造函数会进行预编译 class不会进行预编译

  • 构造函数他可以当作普通函数调用 class不行

new构造函数的时候主要过程

  • 自动创建对象

  • 手动属性赋值

  • 自动返回对象

//对象工厂函数 (忽略细节)
function factory(name){
    //创建一个对象
    let obj = new Object()
    //给对应的属性赋值
    obj.name = name
    //返回这个对象
    return obj
}
let obj = factory('jack')
console.log(obj)

使用工厂函数的主要过程

  • 手动创建对象

  • 手动属性赋值

  • 手动返回对象

封装

抽取对应的属性和方法 (属性为名词方法为动词)

示例

从前有座山 山里有个庙 庙里有老和尚 老和尚对小和尚说 山下的女人是老虎

对象的抽取

class Hill{
    constructor(temple){
        this.temple = temple //属性
    }
}
class Temple{
    constructor(oldMonk){
        this.monk = oldMonk //属性
    }
}
  • 老和尚、小和尚

class Monk{
    constructor(name){
        this.name = name //属性
        this.say = function(monk){
            console.log(`${this.name}对${monk.name}说山下的女人是老虎`)//方法
        }
    }
}

继承

子类继承父类的非私有属性及方法

示例

class的extends关键词来实现继承

//人类
class Person {
    constructor(name, age) {
        this.name = name
        this.age = age
        this.height = 180
        this.eatFood = function () {
            console.log(this.name + '在吃饭')
        }
    }
}
//使用学生类来继承人类
class Student extends Person {
    constructor(name, age, score) {
        super(name, age) //super指向对应的父类的构造函数
        this.score = score
    }
}
let student = new Student('张三', 18, 60)
console.log(student.name) //继承父类的属性
console.log(student.height) //继承父类的属性
student.eatFood() //继承父类的方法
console.log(student.score) //继承父类的属性

多态

一个内容的多种形态主要有俩个表现方式

  • 重载 (在同一个类中有俩个同名的方法 通过参数个数及参数类型来分辨的)(JS没有重载)

class Person{
    constructor(){
    // this.sayHello = function(a){
    // console.log(a)
    // }
    //覆盖上面的函数 因为对应的js是弱类型语言 不能强制指定类型 不能强制指定参数个数
    // this.sayHello = function(a,b){
    // console.log(a,b)
    // }
    //模拟实现
        this.sayHello = function(a,b){
            if(arguments.length==1){
                console.log(a)
            }
            if(arguments.length==2){
                console.log(a,b)
            }
        }
    }
}
new Person().sayHello('hello')
new Person().sayHello('hello','world')
  • 重写 (在子类中重写父类的方法)

class Person{
    constructor(){
        this.sayHello = function(){
            console.log('父类的函数')
        }
    }
}
class Student extends Person{
    constructor(){
        super()
        this.sayHello = function(){
            console.log('重写的函数')
        }
    }
}
new Student().sayHello() //重写的函数

练习

  • 编写⼀个动物类,该类包含name的属性,和say的⽅法。 通过say⽅法可以打印动物说话了。编写⼀个Dog类继承动物类,要求 该类中包含颜⾊的属性,该类重写say⽅法,要求打印⽗类的say⽅法⾥的内容,并且打印 动物颜⾊+动物名字+“叫了”。(备注狗会一直叫)

class Animal {
    constructor(name) {
        this.name = name
    }
    //先编译执行
    say () {
        console.log(this.name + '说话了')
    }
}
class Dog extends Animal {
    constructor(name, color) {
        super(name)
        this.color = color
        this.fn = this.say //接收的父类的say方法
        //重写say方法
        this.say = function () {
            let _this = this
            this.fn()
            setInterval(() => {
                console.log(_this.color + _this.name + '叫了')
            },1000)
        }
    }
}
let dog = new Dog('旺财', '土黄')
dog.say()

tab栏切换案例(面向对象)

  • 提取属性 点击的按钮 切换的内容

  • 提取方法 事件处理的方法 切换的方法

class Tab {
    constructor(naviBar, content) {
        this.naviBar = naviBar //传入的按钮
        this.content = content //传入的内容
        this.index = 0
        //调用handler
        this.handlerClick()
    }
    //切换对应的内容部分
    toggle() {
    //遍历对应的传入的按钮
    //排他
        Array.from(this.naviBar).forEach((btn) => {
            btn.className = ''
        })
    this.naviBar[this.index].className = 'select'
    //遍历对应的传入的内容
    Array.from(this.content).forEach((v) => {
        v.style.display = 'none'
    })
    this.content[this.index].style.display = 'block'
}
handlerClick() {
    var that = this
    //给对应的naviBar添加点击事件
    Array.from(this.naviBar).forEach((btn, i) => {
        btn.onclick = function () {
            that.index = i
            //切换
            that.toggle()
        }
    })
}

//获取所有的a
var bar = document.querySelectorAll('.header>a')
//获取所有的内容
var content = document.querySelectorAll('.content>div')
new Tab(bar,content)

面向对象的拖拽

//拖拽的元素 属性
//拖拽的处理就是对应方法
class Drag {
    constructor(element) {
        this.element = element //拖拽的元素
        //调用对应的鼠标事件
        this.handlerMouseEvent()
    }
    //处理鼠标事件
    handlerMouseEvent() {
    //先按下
    this.element.onmousedown = (e) => {
        e = e || window.event
        //记录按下的位置
        let downPoint = {
            x: e.offsetX,
            y: e.offsetY
        }
        //再移动
        document.onmousemove = (e) => {
            e = e || window.event
            //获取每次移动的位置
            var target = {
                x:e.pageX - downPoint.x,
                y:e.pageY - downPoint.y
            }
            //设置对应的element
            this.element.style.left = target.x + 'px'
            this.element.style.top = target.y + 'px'
        }
        //再弹起
        document.onmouseup = () => {
            document.onmousemove = document.onmouseup = null
        }
    }
}
new Drag(document.querySelector('div'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值