一、简介
面向过程是以一个具体的流程(事务过程)为单位,考虑它的实现过程;面向对象是把任何东西看做是对象,以对象为单位,考虑它的属性及方法。
好比一个木匠在做一把凳子,如果是面向过程的木匠,会想到制作凳子的过程:“先做什么呢?凳子腿?凳子板?用什么工具呢?”。如果是一个面向对象的木
匠,会把所有的东西看做成对象:“凳子腿,凳子板两个对象。凳子腿有属性,长方体的,长度,宽度是多少厘米,有方法钉钉子。凳子板的属性,正方形,边长是多少厘米等等问题”。这样的话,面向对象的木匠会依据这些条件,将一个凳子组装在一起。最终目的是做成一个凳子,用什么思想方法去做,是值得研究的。
通过刚才的例子,会有一种感觉,面向对象的木匠会对事务量化的分析,用“数学”的方法处理问题。
传统开发方法存在问题
1.软件重用性差
重用性是指同一事物不经修改或稍加修改就可多次重复使用,是软件工程追求的目标之一。
2.软件可维护性差
软件工程强调软件的可维护性,强调文档资料的重要性,规定最终的软件产品应该由完整、一致的配置成分组成。在软件开发过程中,始终强调软件的可读性、可修改性和可性。实践证明,用传统方法开发出来的软件,维护时其费用和成本仍然很高,其原因是可修改性差,维护困难。
3.开发出的软件不能满足用户需要
用传统的结构化方法开发大型软件系统涉及各种不同领域的知识,在开发需求模糊或需求动态变化时,所开发出的软件系统往往不能真正满足用户的需要。
的面向对象编程(OOP)有三大特性:封装、继承、多态。
二、封装
封装是指使用权限修饰符private使得属性不能被外界访问。
三、继承
当一个类是另一个类的特例时,这两个类之间具有父子类的关系。子类继承了父类的方法和属性,就是说子类可以重用父类中的这部分代码,继承用关键字extends表示。比如:轿车是车的一个特例,轿车是车的子类,就是说轿车继承了车的一切特性,以下为车子的例子。
- class Che {
- private int wheel = 4;
- public int getWheel() {
- return wheel;
- }
- }
- class Jiaoche extends Che {
- private String pinpai = "桑塔纳";
- public String getPinpai() {
- return pinpai;
- }
- }
- public class Testche {
- public static void main(String[] args) {
- Jiaoche car = new Jiaoche();
- int wheels = car.getWheel(); //调用基类的方法
- String Pinpal = car.getPinpai();//调用本身的方法
- System.out.println("车有 "+wheels+" 个轮子");
- System.out.println("轿车的品牌是 "+Pinpal);
- }
- }
四、多态
类之间的继承关系使子类具有父类的所有变量和方法:父类所具有的方法也可以在它所有子类中使用;发给父类的消息也可以发送给子类;子类的对象也是父类的对象;子类的对象既可以做本身的类型,也可以做父类的类型。举个例子理解上述概念,举例:
public class 动物 //动物是父类
public class 猫 extends 动物 //猫是子类
动物的所有特性在猫中可以使用,发给动物的信息猫也能收到.猫的对象new 猫();既可以作为本身的类型猫 a=new 猫();也可以作为父类的类型 动物 b = new 猫();
推导出结论,所有的子类都可以作为父类的类型(同一种类型)来对待。动物有很多子类,可以有很多对象。动物 a=new 猫(); 动物 b=new 狗(); 动物 c=new
猪();。将子类型的对象引用转换成父类型的对象引用,叫做上溯造型(upcasting)。
数组存放的元素是相同类型的数据,但是上溯造型使得java允许创建不同类型对象的数组,例如:
- Employee[] staff = new Employee[3];
- staff[0] = new Manager();
- staff[1] = new Secretary();
- staff[2] = new Employee();
数组里面不是相同类型吗?是的,因为Sectetary和Manager是Employee的子类,所以也可以通过上溯造型变成Employee啊。以前我们还学到了所有对象都是从java.lang.Object 继承下来的。如果数组要是 Object型的话 Object[] obj=new
Object[];那就是里面放什么对象都行了,因为什么对象都可以是Object型的。
- // java中的多态
- class Shape {
- void draw() {}
- void erase() {}
- }
- //圆形
- class Circle extends Shape {
- void draw() {
- System.out.println("Circle.draw()");
- }
- void erase() {
- System.out.println("Circle.erase()");
- }
- }
- //正方形
- class Square extends Shape {
- void draw() {
- System.out.println("Square.draw()");
- }
- void erase() {
- System.out.println("Square.erase()");
- }
- }
- //三角形
- class Triangle extends Shape {
- void draw() {
- System.out.println("Triangle.draw()");
- }
- void erase() {
- System.out.println("Triangle.erase()");
- }
- }
- public class Shapes {
- public static Shape randShape() {
- switch((int)(Math.random() * 3)) {
- default:
- case 0:
- return new Circle();
- case 1:
- return new Square();
- case 2:
- return new Triangle();
- }
- }
- public static void main(String[] args) {
- Shape[] s = new Shape[9];
- // 向数组里添加类型
- for(int i = 0; i < s.length; i++)
- s[i] = randShape();
- // 用多态的方法调用
- for(int i = 0; i < s.length; i++)
- s[i].draw();
- }
- }
多态性的突出优点是使程序具有良好的扩展性,它通过继承,可以派生出任意多个新类型,或向基类增加更多方法时无须修改原有对基础类进行处理的相关程序。
五、重载与重写
方法重载(overloading method) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
方法重写(overiding method) 子类不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
方法重载实例:
- public class MethodOverloading {
- void recieve(int i) {
- System.out.println("接收一个int数据");
- System.out.println("i="+i);
- }
- void recieve(float f) {
- System.out.println("接受一个float型的数据");
- System.out.println("f="+f);
- }
- void recieve(String s) {
- System.out.println("接受一个String型数据");
- System.out.println("s="+s);
- }
- public static void main(String[] args) {
- MethodOverloading m = new MethodOverloading();
- m.recieve(3456);
- m.recieve(34.56);
- m.recieve("agagagfg");
- }
- }
上面的例子,方法receive()有三个,名字相同参数不同。这样的话,在main()调用的时候,参数用起来就很方便了。
有时候,重载和重写的方式有些复杂。在jdk5里面,有一些方式(可变参数)能简化一些。如果把相同参数类型的方法重载好几遍真的是很烦。例如,pri(String
args), pri(String arg0 ,String arg1), pri(String arg0,String
arg1,String arg2), pri(String arg0,String arg1,String arg2,String arg3),这样的话会写很多烦琐的代码。现在jdk5可以用“…”来代替这些参数。
- public class overload {
- //若干个相同类型的参数,用“...”代替
- public void pri(String... strings ){
- for (String str : strings) //for这个循环语句也有迭代的意思
- System.out.print(str);
- }
- public static void main(String[] args){
- new overload().pri("100jq"," afaf"," afdvvvv.");
- }
- }
jdk5的方法重写,比以前多了一个叫做协变返回的概念。在以往jdk的版本中,还有一个比较让人讨厌的地方。方法重写确实是比较不错的机制,如果想用父类的方法,写个super就可以了,如果不想用父类的方法就重写覆盖。但是重写覆盖的返回类型不能覆盖,父类的类型不够用怎么办,想在子类重写它的类型可以吗?可以,例如:
- class Point2D { //定义二维的点
- protected int x, y;
- public Point2D() {
- this.x=0;
- this.y=0;
- }
- public Point2D(int x, int y) {
- this.x = x;
- this.y = y;
- }
- }
- //定义三维的点,继承二维
- class Point3D extends Point2D {
- protected int z;
- public Point3D(int x, int y) {
- this(x, y, 0);
- }
- public Point3D(int x, int y, int z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
- }
- //定义二维的位置
- class Position2D {
- Point2D location;
- public Position2D() {
- this.location = new Point2D();
- }
- public Position2D(int x, int y) {
- this.location = new Point2D(x, y);
- }
- public Point2D getLocation() {
- return location;
- }
- }
- //定义三维的位置,继承二维的位置
- class Position3D extends Position2D {
- Point3D location; //在这里已经变成Point3D的类型了
- public Position3D(int x, int y, int z) {
- this.location = new Point3D(x, y, z);
- }
- @Override //注释是重写方法
- public Point3D getLocation() {
- return location; //返回是子类的类型而不是原来的类型了
- }
- }
阅读(1565) | 评论(0) | 转发(0) |