什么是面向过程与面向对象?
面向过程
:面向过程就是分析出解决问题需要的步骤,然后用函数把这些步骤一个个实现,使用的时候依次调用。面向过程的核心是过程。
面向对象
:面向对象就是把需要解决的问题分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述每个对象在解决问题中的行为,面向对象的核心是对象。
面向对象的优势
1、模块化更深,封装性强。
2、更容易实现复杂的业务逻辑。
3、更易维护、易复用、易扩展。
面向对象的特征
(1)封装性:对象是属性(静态特征)和行为(动态特征)的结合体(封装体)
(2)继承性:父类(基类)的属性和行为可以派生到子类中。子类不需要重复定义
(3)多态性:同一个消息传递给不同的对象,得到的结果不同。
创建类的方法
ES5中通过构造函数实现
function Student(name,age){ //构造函数,建议首字母大写,Student可以看作类
this.name = name;
this.age = age;
}
ES6中用class关键字定义一个类
class关键字:用来定义一个类,在类中可以定义constructor()构造方法,用来初始化对象的成员。在ES6中constructor构造方法不能显式调用。
// 定义类
class Person {
constructor(name) {
this.name = name; }
}
创建对象
基础语法
var 对象名 = new 类名([参数])
对象成员(包括属性和方法)的访问
对象名.属性名
对象名.方法名([参数])
练习
设计雇员Employee类,记录雇员的情况,包括姓名、年薪、受雇时间,要求定义MyDate类作为受雇时间,其中包括工作的年、月、日,并用相应的方法(构造方法、显示信息的方法)对Employee类进行设置。
class MyDate
{
constructor(n,y,r){
this.n = n;
this.y = y;
this.r = r;
}
display(){
console.log(this.n+'年'+this.y+'月'+this.r+'日');
}
}
class Employee{
constructor(name,mally,MyDate){
this.name = name;
this.mally = mally;
this.MyDate = MyDate;
}
show(){
console.log('姓名:'+this.name);
console.log('年薪:'+this.mally);
console.log('受雇时间:');
this.MyDate.display();
}
}
var work1 = new MyDate(2021,6,15);
var em1 = new Employee();
em1.name = '张三';
em1.mally = 100000;
em1.MyDate = work1;
em1.show();
实例成员和静态成员
(1)实例成员:对象成员。
(2)静态成员:所有对象共享的成员,不属于某个具体的对象。又称为类成员。
静态成员的创建方式
类名.成员名 -- ES6
构造方法名.成员名 -- ES5
练习
class Student{
constructor(name){
this.name = name;
}
show(){
console.log('学校:',Student.school);
console.log('姓名:',this.name);
}
}
Student.school = "北京大学";//静态成员,不属于某一个具体的对象
var s1 = new Student('张三');
var s2 = new Student('李四');
s1.show();
s2.show();
类的继承
在JavaScript中,继承用来表示两个类之间的关系,子类可以继承父类的一些属性和方法,在继承以后还可以增加自己独有的属性和方法。
在此我着重讨论ES6中的继承方法。ES5实现类的继承在我前面写的(7种方法实现ES5中的继承)中。
(1)父类:又称为基类或超类,被继承的类
(2)子类:又称为派生类。由父类派生来的类
(3)继承的实现:extends
基础语法
class 子类名 extends 父类名{
constructor(){
}
其他的成员方法
}
super关键字:super关键字用于访问和调用
对象在父类上的方法,可以调用父类的构造方法,也可以调用父类的普通方法。
注意:
A、调用父类的构造方法:在子类的构造方法中调用父类的构造方法在继承中,创建子类对象时必须先调用父类的构造方法
,然后再调用子类的构造方法,并且父类构造方法的调用必须是子类构造方法中第一条语句
。
B、super([参数]):调用父类的构造方法 。
C、调用父类的普通方法:super.方法名([参数])。
练习
通过一个点类(Point),具有自己的坐标位置(x,y),和显示本类信息的show()方法;一个圆类(Circle)由点类派生,增加一个新的属性半径(radiu),一个计算圆面积的area()方法,和一个同样显示本类信息的show()方法;一个圆柱体类(Cylinder)由圆类派生,增加一个属性高度(height),一个计算圆柱形体积的方法vol(),一个计算圆柱形表面积的area()方法,和一个同样显示本类信息的show()方法。建立一个主类,调用相关类的方法,并打印出相应的信息。
class point{
constructor(x,y){
this.x = x;
this.y = y;
}
show(){
console.log('('+this.x+','+this.y+')');
}
}
class Circle extends point{
constructor(point,r){
super(point.x,point.y);
this.r = r;
}
area(){
var s =Math.PI*Math.pow(this.r,2);
return s;
}
show(){
super.show();
console.log('半径'+this.r);
console.log('圆的面积'+this.area());
return
}
}
class Cylinder extends Circle{
constructor(point,r,h){
super(point,r);
this.h = h;
}
vol(){
var q = super.area()*this.h
return q;
}
area1(){
var x = super.area()*2+Math.PI*2*this.r*this.h;
return x;
}
show(){
super.show();
console.log('高度:'+this.h);
console.log('圆柱体表面积'+this.area1());
console.log('圆柱体体积:'+this.vol());
}
}
var point1 = new point(3,0);
var Circle1 = new Circle(point1,2);
var Cylinder1 = new Cylinder(point1,2,4);
Circle1.show();
console.log('-------------------');
Cylinder1.show();