面相对象开发有三大特征: 封装, 继承, 多态
封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>封装</title>
</head>
<body>
<script>
// 封装: 把一些代码存储在一起, 后续可以复用
function get(url, cb) {
var xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.send()
xhr.onload = function () {
cb(JSON.parse(xhr.response))
}
}
// 复用: 重复使用
get('https://api.xin88.top/car/news.json', data => {
console.log(data)
})
var emp = { ename: "关关", age: 22 }
</script>
</body>
</html>
继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>继承</title>
</head>
<body>
<!-- 继承: 1个人可以拥有另外一个人的所有资源 -->
<!-- 面相对象中的继承: 子类 可以拥有 父类的 所有属性和方法 -->
<script>
// 提取公共的代码
class Animal {
constructor(name, category) {
this.name = name
this.category = category
}
}
// 制作几个构造函数: 猫 狗 羊
// extends: 继承; Cat就可以使用Animal中的方法
class Cat extends Animal {
// constructor(name, category) {
// this.name = name
// this.category = category
// }
cry() {
console.log('喵喵...');
}
}
class Dog extends Animal {
// constructor(name, category) {
// this.name = name
// this.category = category
// }
cry() {
console.log('汪汪...');
}
}
class Sheep extends Animal {
// constructor(name, category) {
// this.name = name
// this.category = category
// }
cry() {
console.log('咩咩...');
}
}
var cat_mimi = new Cat('咪咪', 4)
var dog_wangcai = new Dog('旺财', 5)
var sheep_duoli = new Sheep("多利", 3)
console.log(cat_mimi);
console.log(dog_wangcai);
console.log(sheep_duoli);
</script>
</body>
</html>
多态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多态 15:17</title>
</head>
<body>
<!-- 继承: 1个人可以拥有另外一个人的所有资源 -->
<!-- 面相对象中的继承: 子类 可以拥有 父类的 所有属性和方法 -->
<script>
// 提取公共的代码
class Animal {
constructor(name, category) {
this.name = name
this.category = category
}
// 公共的方法: 所有动物都会 叫, 但是具体如何叫要看具体的子类
cry() { }
}
class Cat extends Animal {
// 重写: override; 把父元素提供的属性 重新书写
cry() {
console.log('喵喵...');
}
}
class Dog extends Animal {
cry() {
console.log('汪汪...');
}
}
class Sheep extends Animal {
cry() {
console.log('咩咩...');
}
}
var cat_mimi = new Cat('咪咪', 4)
var dog_wangcai = new Dog('旺财', 5)
var sheep_duoli = new Sheep("多利", 3)
console.log(cat_mimi);
console.log(dog_wangcai);
console.log(sheep_duoli);
// 同样的方法, 由于子类的重写, 使用时出现不同的状态: 多态
cat_mimi.cry()
dog_wangcai.cry()
sheep_duoli.cry()
</script>
</body>
</html>
继承function
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>继承: function</title>
</head>
<body>
<!--
构造函数的发展过程:
早期: 用 function 实现: 在实现继承时特别复杂.
ES6之后: class 语法; 更简单 更易用, 广受欢迎
实际开发中, 很少见到 用 function 实现继承的
但是: 面试会考
-->
<script>
function Animal(name, category) {
this.name = name
this.category = category
}
Animal.prototype.cry = function () { }
// 继承写法:
function Cat(name, category) {
// 触发Animal的构造方法
Animal.call(this, name, category)
// call(): 触发函数, 并且指定函数中的this指向
// 把 cat 对象传递给 Animal 进行初始化的赋值
}
// 修改Cat 的原型的原型 为 Animal 的原型
// create: 创建一个对象, 对象的原型是 Animal.prototype
Cat.prototype = Object.create(Animal.prototype)
Cat.prototype.constructor = Cat //设置原型的构造函数
console.dir(Cat)
</script>
</body>
</html>