面向对象的简单理解
在本文开始之前,我们需要先了解可维护,可复用和可扩展是什么意思?这里以印刷术为例.在活字印刷术出现以前,要改字,加字,重新排列的时候就必须重刻.印完这本书后,此版就没有任何了利用价值.而在活字印刷术出现以后,我们改字,只需要更改要改之字.这就是可维护.而且这些字并不是用完这次后就无用,完全可以在后来的印刷中重复使用,这就是可复用,如果需要加字,那就只需要另刻字即可,这就是可扩展.
我们都知道面向对象的三大特性是封装,继承和多态.这三种特性可以使代码的耦合度降低.那么这种对代码耦合度的降低是如何体现出来的,本文来跟大家一起探讨.
编写一个计算器控制台程序,要求输入两个整数和运算符号,得到结果. 下面是实现过程.
System.out.println("请输入数A:");
int numA = new Scanner(System.in).nextInt();
System.out.println("请输入运算符 + - * / :");
String calcu=new Scanner(System.in).next();
System.out.println("请输入数B");
int numB = new Scanner(System.in).nextInt();
int result=0;
switch (calcu){
case "+": result= numA + numB; break;
case "-": result=numA - numB;break;
case "*": result=numA * numB;break;
case "/": result=numA / numB;break;
}
System.out.println("结果为:"+result); 
这种方式虽然把功能实现了,但它是面向过程式的编程方式,也就是一步一步地实现代码逻辑,如果其他地方要用到这个计算器地功能还要再重复写一次.不是很方便调用.那我以后其他地方也想要调用计算器的功能要怎么实现呢?
public class Calculate {
    public static void main(String[] args){
        System.out.println("请输入数A:");
        int numA = new Scanner(System.in).nextInt();
        System.out.println("请输入运算符 + - * / :");
        String calcu=new Scanner(System.in).next();
        System.out.println("请输入数B");
        int numB = new Scanner(System.in).nextInt();
        int result = Operation.getResult(calcu, numA, numB);
        System.out.println("结果为:"+result);
    }
   
} 
public class Operation {
    public static int getResult(String calcu,int numA,int numB){
        int result=0;
        switch (calcu){
            case "+": result= numA + numB; break;
            case "-": result=numA - numB;break;
            case "*": result=numA * numB;break;
            case "/": result=numA / numB;break;
        };
        return result;
    };
}
通过上面的例子可以看出,为了实现代码的复用,我把计算的这个过程写成了一个函数,这样的话其他类就方便调用这个计算功能,不用再重复去写了,只需要调用这个函数就行.这个过程就是函数的封装,除了实现代码的复用还有其他要进行封装的原因嘛?答案是有的.当重复的代码多到一定程度,维护的时候可能就是一场灾难.所以我们应该尽量避免代码的重复.更加重要的是我们把运算的逻辑和界面逻辑分开,让它们的耦合度下降,代码更易维护.
但仅仅使用封装来降低代码耦合度就足够吗,如果我现在要再给计算器新增一个开平方的功能那要怎么做呢,以后还要给这个计算器增加其他功能呢?在代码量少的时候你可以通过直接修改代码来达到目的,但是如果业务打码量非常庞大的时候,你对代码的直接修改就是牵一发而动全身.后续代码的可维护性会很差.所以这时候我们就可以了解到程序设计的开闭原则(对扩展开放,对修改关闭)有多香了.我们可以利用面向对象的继承和多态这两个特性来进一步地降低我们代码的耦合度.
//抽离出公共的计算行为作为父类,具体的加减乘除运算由子类去重写方法来实现
public abstract class Operation { abstract int getResult(int numA,int numB); } //加法 public class OperationAdd extends Operation{ @Override int getResult(int numA,int numB) { return numA + numB; } } //减法 public class OperationDel extends Operation{ @Override int getResult(int numA, int numB) { return numA - numB; } } //乘法 public class OperationMulti extends Operation{ @Override int getResult(int numA, int numB) { return numA * numB; } } //除法 public class OperationDiv extends Operation { @Override int getResult(int numA, int numB) { return numA / numB; } }
//利用工厂模式 + 多态 来进行对象的生产
public class OperationFactory {
    
    public static Operation createOperation(String calcu){
            switch (calcu){
                case "+" :{
                    //父类引用指向子类对象,这个就是多态
                    Operation operationAdd = new OperationAdd();
                    return operationAdd;
                }
                case "-":{return new OperationDel();}
                case "*":{return new OperationMulti();}
                case "/":{return new OperationDiv();}
            }
        return null;
    }
}
System.out.println("请输入数A:");
int numA = new Scanner(System.in).nextInt();
System.out.println("请输入运算符 + - * / :");
String calcu=new Scanner(System.in).next();
System.out.println("请输入数B");
int numB = new Scanner(System.in).nextInt();
Operation operation =OperationFactory.createOperation(calcu);
int result = operation.getResult(numA, numB);
System.out.println("结果为:"+result);
在父类中定义抽象的功能,通过子类继承父类重写父类的方法来完成新增的功能增加,这样的话新增计算功能可以不用直接对原代码进行修改,我只需要新增一个子类重写父类方法即可.同时程序的可扩展性大大增强.且简单工厂 + 多态的使用也进一步降低了代码的耦合度.
总结:以上的例子就是从面向过程式编程逐步演变到面向对象式编程的过程,这也是代码耦合度不断降低的过程.通过封装我们提高了代码的复用性,继承和多态也提高了代码的可维护性和扩展性
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号