这篇文章主要为大家详细介绍了Javascript中的面向对象入门实例(一),具有一定的参考价值,可以用来参考一下。
在学习Javascript的过程中,面向对象是必须要学会的课题。然而,网络上大部分文章只是简单地讲述如何通过代码实现面向对象,忽略了理论和原理方面的知识。本系列文章将从头开始逐步讲解面向对象编程思想及其在Javascript中的实现与应用。
// 来自:四海网(www.q1010.com)
var rectangle = {
name: '长方形1',
type: 'rectangle',
length: 5, // 长
width: 10 // 宽
};
var square = {
name: '正方形1',
type: 'square',
length: 5 // 边长
};
var circle = {
name: '圆形1',
type: 'circle',
radius: 5 // 半径
};
function computePerimeter(shape) {
var result;
switch (shape.type) {
case 'rectangle':
// 矩形周长:(长+宽)*2
result = (shape.length + shape.width) * 2;
break;
case 'square':
// 正方形周长:边长*4
result = shape.length * 4;
break;
case 'circle':
// 圆形周长:2*PI*半径
result = 2 * Math.PI * shape.radius;
break;
}
return shape.name + '的周长是' + result;
}
但这种实现方式有着不少缺陷:
// 来自:四海网(www.q1010.com)
class Square
{
public string Name;
public double Length;
public Square()
{
this.Length = 1;
}
public double Perimeter()
{
return this.Length * 4;
}
}
类可以有属性和方法。上面代码中的Name和Length为属性,分别是字符串和浮点数类型;而Perimeter则为方法,它没有参数,返回值是浮点数类型。声明属性和方法时还可以加上访问修饰符:public、private或protected(用处后面再详细介绍)。类中还有一个名字跟类名一样的特殊函数,即构造函数,这个函数在创建实例时自动调用。
// 来自:四海网(www.q1010.com)
Square square = new Square();
square.Perimeter(); // 构造函数中给Length属性赋值为1,因此结果为4
square.Length = 10;
square.Perimeter(); // 给Length属性赋值为10,因此结果为40
接下来声明矩形类和圆形类:
// 来自:四海网(www.q1010.com)
class Rectangle
{
public string Name;
public double Length;
public double Width;
public double Perimeter()
{
return (this.Length + this.Width) * 2;
}
}
class Circle
{
public string Name;
public double Radius;
public double Perimeter()
{
return 2 * Math.PI * Radius;
}
}
// 来自:四海网(www.q1010.com)
class Shape
{
public string Name;
public double Perimeter()
{
// do what?
}
}
答案是不实现。在面向对象的概念中,所有对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的。某些类中没有包含足够的信息来描绘具体的对象,也就无法实例化,只能作为基类存在,这样的类就是抽象类。而Shape正是这样一个类:
// 来自:四海网(www.q1010.com)
abstract class Shape
{
public string Name;
public abstract double Perimeter();
}
抽象类通过abstract关键字声明,可以包含抽象方法。抽象方法只有方法声明,没有具体实现,它存在的意义是,强制子类必须存在这样一个方法并且实现它。
// 来自:四海网(www.q1010.com)
class Square : Shape
{
public double Length;
public override double Perimeter()
{
return this.Length * 4;
}
}
class Rectangle : Shape
{
public double Length;
public double Width;
public override double Perimeter()
{
return (this.Length + this.Width) * 2;
}
}
class Circle : Shape
{
public double Radius;
public override double Perimeter()
{
return 2 * Math.PI * Radius;
}
}
C#中通过冒号来表示继承,冒号后面的为父类。由于Shape类的三个子类都继承了Name这个属性,所以不需要再声明一次了。它们又都实现了Perimeter方法,但实现各不相同,这就是面向对象中的多态——一种定义,多种实现。
// 来自:四海网(www.q1010.com)
Shape shape = new Circle();
不过要注意,此时shape变量仍然是Shape类型,而非Circle类型,所以不能访问它的Radius属性:
// 来自:四海网(www.q1010.com)
Shape shape = new Circle();
shape.Radius = 10; // 编译失败
但这样写是没有问题的:
// 来自:四海网(www.q1010.com)
Circle circle = new Circle();
circle.Radius = 10;
Shape shape = circle;
// 来自:四海网(www.q1010.com)
Square square = new Square();
square.Length = -10;
很明显,正方形的边长不可能为负数。然而,给Length赋值为负数却是合法的。为了阻止这种非法值,面向对象提供了封装这一特性。
// 来自:四海网(www.q1010.com)
class Square
{
private double Length;
// 其他照抄
}
Square square = new Square();
double length = square.Length; // 读操作,编译失败
square.Length = 10; // 写操作,编译失败
那么问题来了,如果要访问Length的值,该怎么办?答案就是通过public的方法:
// 来自:四海网(www.q1010.com)
class Square
{
private double Length;
public double GetLength()
{
return this.Length;
}
public void SetLength(double length)
{
if (length < 0) { throw new Exception("…"); }
this.Length = length;
}
public double Perimeter()
{
return this.Length * 4;
}
}
Square square = new Square();
square.SetLength(10);
虽然Length属性是private的,但GetLength和SetLength方法是public的,通过调用它们就间接获取或修改Length的值。并且,SetLength对传入的参数进行了判断,如果是非法值就抛出异常,这样就保证了值是合法的。
// 来自:四海网(www.q1010.com)
// 形状
abstract class Shape
{
protected string Name;
public string GetName() { return this.Name; }
public void SetName(string name) { this.Name = name; }
public abstract double Perimeter();
}
// 正方形
class Square
{
private double Length;
public double GetLength() { return this.Length; }
public void SetLength(double length)
{
if (length < 0) { throw new Exception("…"); }
this.Length = length;
}
public double Perimeter()
{
return this.Length * 4;
}
}
// 长方形
class Rectangle : Shape
{
private double Length;
public double GetLength() { return this.Length; }
public void SetLength(double length)
{
if (length < 0) { throw new Exception("…"); }
this.Length = length;
}
private double Width;
public double GetWidth() { return this.Width; }
public void SetWidth(double width)
{
if (width < 0) { throw new Exception("…"); }
this.Width = width;
}
public double Perimeter()
{
return (this.Length + this.Width) * 2;
}
}
// 圆形
class Circle : Shape
{
private double Radius;
public double GetRadius() { return this.Radius; }
public void SetRadius(double radius)
{
if (radius < 0) { throw new Exception("…"); }
this.Radius = radius;
}
public double Perimeter()
{
return 2 * Math.PI * Radius;
}
}
接着编写ComputePerimeter函数并调用:
// 来自:四海网(www.q1010.com)
string ComputePerimeter(Shape shape)
{
return shape.GetName() + '的周长是' + shape.Perimeter();
}
Square square = new Square();
square.SetLength(5);
ComputePerimeter(square);
Circle circle = new Circle();
circle.setRadius(5);
ComputePerimeter(circle);
多态的作用在此刻显现:
// 来自:四海网(www.q1010.com)
// 三角形类
class Triangle : Shape
{
private double sideA;
private double sideB;
private double sideC;
public double GetSideA() { return this.sideA; }
public double GetSideB() { return this.sideB; }
public double GetSideC() { return this.sideC; }
public void SetSides(double a, double b, double c)
{
if (a < 0 || b < 0 || c < 0)
{
throw new Exception('...');
}
// 两边之和必须大于第三边
if (a + b <= c || a + c <= b || b + c <= a)
{
throw new Exception('...');
}
// 两边之差的绝对值必须小于第三边
if (Math.Abs(a - b) >= c || Math.Abs(a - c) >= b || Math.Abs(b - c) >= a)
{
throw new Exception('...');
}
this.sideA = a;
this.sideB = b;
this.sideC = c;
}
public override double Perimeter()
{
return this.sideA + this.sideB + this.sideC;
}
}
var triangle = new Triangle();
triangle.setSides(3, 4, 5);
ComputePerimeter(triangle);
小结本文来自:http://www.q1010.com/174/1652-0.html
注:关于Javascript中的面向对象入门实例(一)的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。
关键词:面向对象
四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。