首页 > 其他 > 详细

面向对象

时间:2020-06-27 22:38:15      阅读:78      评论:0      收藏:0      [点我收藏+]

面向对象

面向对象概念

理解面向对象

  • 面向对象是相对于面向过程而言的
  • 面向对象和面向过程都是一种思想
  • 面向过程强调的是功能行为,如
    • 打开冰箱
    • 存储进冰箱
    • 关闭冰箱
  • 面向对象是将功能封装进对象,强调具备了功能的对象,如
    • 冰箱.打开
    • 冰箱.存储
    • 冰箱.关闭
  • 面向对象是基于面向过程的

面向对象的特点

  • 面向对象思想是一种更符合我们思考习惯的思想
  • 可以将复杂的事情简单化
  • 将我们从执行者转换成了指挥者。
  • 完成需求时:
    • 先要去找具有所需要的功能的对象来用。
    • 如果该对象不存在,那么创建一个具有所需功能的对象,这样简化开发并提高复用。
  • 面向对象的语言中,包含了三大基本特征,即封装、继承和多态。

面向对象的开发与设计

  • 开发的过程其实就是不断地创建对象,使用对象,指挥对象做事情。
  • 设计的过程其实就是在管理和维护对象之间的关系。

类与对象的关系

类与对象

  • 类就是对现实生活中事物的描述。对象就是这类事物实实在在存在的个体。
  • Java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义。

类的定义

  • 生活中描述事物无非就是描述事物的属性和行为。如:
    • 人有身高、属性等属性。
    • 人有说话、打球等行为。
  • Java中用类class来描述事物也是如此
    • 属性:对应类中的成员变量
    • 行为:对应类中的成员方法
  • 定义类其实就是在定义类中的成员(成员变量和成员方法)

成员变量和局部变量

  • 成员变量
    • 成员变量定义在类中,在整个类中都可以被访问
    • 成员变量随着对象的建立而建立,存在于对象所在的堆内存中
    • 成员变量有默认初始值
  • 局部变量
    • 局部变量只能定义在局部范围内,如:方法内,语句内等
    • 局部变量存在于占内存中
    • 作用的范围结束,变量空间会自动结束。
    • 局部变量没有默认初始值

对象的创建与使用

对类的描述

class Car{//对Car这类事物进行描述
    String color = "red";
    int num = 4;
    
    void show(){
        System.out.println("color="+color+",num="+num);
    }
}

创建和使用对象

class CarDemo{
    public static void main(String[] args){
        Car c = new Car();//建立对象
        C.color = "black";//对对象的属性进行修改
        c.show();//使用对象的功能
    }
}

对象内存结构

技术分享图片

对象的初始化过程

Person p = new Person("zhangsan",20);

上面这条语句在执行过程中做了哪些事?

  1. 因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。
  2. 执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
  3. 在堆内存中开辟空间,分配内存地址。
  4. 在堆内存当中建立对象的特有属性,并进行默认初始化。
  5. 对属性进行显示初始化。
  6. 对对象进行构造代码块初始化。
  7. 对对象进行对应的构造方法进行初始化。
  8. 将内存地址交给栈内存中的p变量。

匿名对象

  • 匿名对象是对象的简化形式

  • 匿名对象的两种使用形式

    1. 当对对象方法仅进行一次调用时可以使用匿名对象。
    • 这样写比较简化
    • 如果对一个对象进行多个成员调用,必须给这个对象起个名字(即不能使用匿名对象进行操作)
    • 注意:使用匿名对象对对象的成员方法进行调用时有意义的,而对对象的成员变量进行调用时无意义的。凡是简化的都会有局限性。
    class CarDemo{
        public static void main(String[] args){
            Car c = new Car();//建立对象
            C.color = "black";//对对象的属性进行修改
            c.show();//使用对象的功能
            
            /*用匿名对象的方式操作如下*/
            new Car().num = 5;
            new Car().color = "blue";
            new Car().show();
        }
    }    
    
    1. 匿名对象可以作为实际参数进行传递。
    class CarDemo{
        public static void main(String[] args){
            Car c = new Car();//建立对象
            show(c);//调用show()方法
            
         /*将匿名对象作为实际参数进行传递,调用show()方法,如下操作*/
            show(new Car());
        }
        
        public static void show(Car c){
            c.num = 3;
            c.color = "black";
            c.run();
        }
    }
    

封装

什么是封装

  • 封装是指隐藏对象的属性和实现细节,对外提供公共访问方式。
  • 方法和类也是一种封装。
  • 注意:私有仅仅是封装的一种表现形式。

封装的好处

  • 将变化隔离
  • 便于使用
  • 提高重用性
  • 提高安全性

封装的原则

  • 将不需要对外提供的内容都隐藏起来。
  • 把属性都隐藏,提供公共方法对其访问。
    • 之所以对外提供访问方式,是因为可以在访问方式中加入逻辑判断语句。
    • 对访问的数据进行操作,提高代码的健壮性。

private关键字

  • private关键字是一种修饰符,表示私有的。
  • 用于修饰类中的成员(成员变量、成员方法),私有的只在本类中有效。

代码演示

class Person{
    private int age;
    public void setAge(int a){
        if(a>0 && a<130){
             age = a;
            speak();
        }
        else
            System.out.println("年龄有误!");
    }
    public void getAge(){
        return age;
    }
    
    void speak(){
        Syetem.out.println("age="+age);
    }
}

class PersonDemo{
    public static void main(String[] args){
        Person p = new Person();
        p.setAge = 20;
        p.speak();
    }
}

构造方法

构造方法的特点

  • 方法名和类名相同
  • 不用定义返回值类型
  • 不可以写return语句
class Person{
    Person(){//构造方法
        System.out.println("Person run!");
    }
}
class PersonDemo{
    public static void main(String[] args){
        Person p = new Person();
    }
}

构造方法的作用

  • 可以用于给对象进行初始化。对象一建立就会调用与之对应的构造方法

构造方法的小细节

  • 当一个类中没有定义构造方法时,系统会默认给该类加入一个空参数的构造方法。
  • 当类中自定义了构造方法后,默认的构造方法就不再提供了。
  • 多个构造方法是以重载的形式存在的。
  • 一个类中默认会有一个空参数的构造方法,这个默认的构造方法的权限和所属类一致。
    • 如果类被public修饰,那么默认的构造方法也带有public修饰。
    • 如果类没有被public修饰,那么默认的构造方法,也没有public修饰。
  • 默认构造方法的权限是随着类的变化而变化的。

构造方法与一般方法的区别

  • 构造方法和一般方法在写法上有区别
  • 在运行上也有不同
    • 构造方法是在对象一建立就运行,给对象初始化,而一般方法是对象调用才执行,给对象添加对象具备的功能。
    • 一个对象建立,构造方法只执行一次,而一般方法可以被该对象调用多次。

什么时候定义构造方法?

  • 当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。

构造代码块

  • 构造代码块中定义的是不同对象的共性的初始化内容
  • 作用:给对象进行初始化
  • 对象一建立就运行,而且优先于构造方法执行。
  • 与构造方法的区别:
    • 构造代码块是给所有对象进行统一初始化
    • 而构造方法是给对应的对象初始化。
{
    System.out.println("这是一个构造代码块!")
}

this关键字

this关键字的特点

  • this代表其所在方法所属对象的引用。
  • 简单说:哪个对象在调用this所在的方法,this就代表哪个对象。

this语句

  • this语句用于构造方法之间进行相互调用
  • this语句只能定义在构造方法的第一行。因为初始化要先执行。

this的应用

  • 当定义类中功能时,该方法内部要用到调用该方法的对象时,这时用this来表示这个对象。
  • 但凡本类功能内部使用了本类对象,都用this表示。

static关键字

static关键字作用

  • static是一个修饰符,用于修饰成员(成员变量、成员方法)

被修饰后的成员具备以下特点

  • 随着类的加载而被加载。也就说,静态会随着类的消失而消失,说明它的生命周期最长。
  • 优先于对象存在。明确一点,静态是先存在的,对象是后存在的。
  • 被所有对象所共享
  • 可以直接被类名调用。格式:类名.静态成员
class Person{
    String name;//成员变量,实例变量
    static String country = "CN";//静态的成员表变量,类变量
}

实例变量与类变量的区别

  1. 存放位置
    • 类变量随着类的加载而存在于方法区中。
    • 实例变量随着对象的建立而存在于堆内存中。
  2. 生命周期
    • 类变量的生命周期最长,随着类的消失而消失。
    • 实例变量生命周期随着对象的消失而消失。

静态使用的注意事项

  1. 静态方法只能访问静态成员。非静态方法既可以访问静态也可以访问非静态。
  2. 静态方法中不可以定义thissuper关键字。因为静态优先于对象存在,所以静态方法中不可以出现this
  3. 主方法是静态的。

静态的优缺点

  • 优点
    • 对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中存储一份。
    • 可以直接被类名调用,不必创建对象后使用对象调用。
  • 缺点
    • 生命周期过长。会随着类的消失而消失。
    • 访问存在局限性。(静态虽好,只能访问静态)

什么时候使用静态?

  • 要从两方面下手。因为静态修饰的内容有成员方法和成员变量

    • 什么时候定义静态变量(类变量)呢?

      • 当对象中出现共享数据时,该数据被静态所修饰。
      • 对象中的特有数据要定义成非静态存在于堆内存中。
    • 什么时候定义静态方法?

      • 当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义成静态的。
      class Person{
          String name;
          public void show1(){
              System.out.println(name+"heihei");
          }
          public static void show2(){
              System.out.println("haha");
          }
      }
      class PersonDemo{
          public static void main(String[] args){
              Person p = new Person();
              p.show1();
              
              Person.show2();
          }
      }
      

静态的应用----工具类

每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装,以便复用。

class ArrayTool{
    private ArrayTool(){}
    public static int getMax(int[] arr){//获取最大值
        int max = 0;
        for(int x=1; x<arr.length; x++){
            if(arr[x] > arr[max])
                max = x;
        }
        return arr[max];
    }
    public static int getMin(int[] arr){//获取最小值
        int min = 0;
        for(int x=1; x<arr.length; x++){
            if(arr[x] < arr[min])
                min = x;
        }
        return arr[min];
    }
    public static void selectSort(int[] arr){//选择排序
        for(int x=0; x<arr.length-1; x++){
            for(int y=x+1; y<arr.length; y++){
                if(arr[x] > arr[y]){
                    swap(arr,x,y);
                }
            }
        }
    }
    public static void bubbleSort(int[] arr){//冒泡排序
        for(int x=0; x<arr.length-1; x++){
            for(int y=0; y<arr.length-x-1; y++){
                if(arr[y] > arr[y+1]){
                    swap(arr,y,y+1);
                }
            }
        }
    }
    private static void swap(int[] arr, int a, int b){//交换数据
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
    public static void printArray(int[] arr){//打印数组
        System.out.print("[");
        for(int x=0; x<arr.length; x++){
            if(x! = arr.length-1)
                System.out.print(arr[x]+", ");
            else
                System.out.print(arr[x]+"]");
        }
    }
}

class ArrayToolDemo{
    public static void main(String[] args){
        int[] arr = {2,6,34,83,9,6,};
        /*ArrayTool tool = new ArrayTool();
        int max = tool.getMax(arr);
        System.out.println("max="+max);*/
        int max = ArrayTool.getMax(arr);
        System.out.println("max="+max);
    }
}

从以上代码可以看出,虽然可以通过建立ArrayTool的对象使用工具方法,对数据进行操作。发现了问题:

  1. 对象是用于封装数据的,可是ArrayTool并未封装特有数据。
  2. 操作数据的每一个方法都没有用到ArrayTool对象中的特有方法。

这时就考虑,让程序更严谨,是不需要对象的。可以将ArrayTool中的方法都定义成static的。直接通过类名调用。

通常工具类中定义的都是静态方法。

将方法静态后,可以方面使用,但是该类还是可以被其他程序建立对象的,为了更为严谨,强制让该类不能建立对象。可以通过构造方法私有化完成。

能隐藏起来的都隐藏起来。

接下来,将ArrayTool.class文件发送给其他人,其他人只要将该文件设置到classpath路径下,就可以使用该工具类。但是,很遗憾,该类中到底定义了多少个方法,对方却不清楚。因为该类并没有使用说明书。

开始制作程序的说明书,java的说明书通过文档注释来完成。

/**
这是一个可以对数组进行操作的工具类,该类中提供了获取最值,排序等功能。
@author 小杨
@version v1.2
*/
public class ArrayTool{
    /**
    空参构造方法
    */
    private ArrayTool(){}
    /**
    获取一个整形数组中的最大值
    @param arr 接收一个int类型的数组。
    @return 会返回一个该数组中最大值
    */
    public static int getMax(int[] arr){//获取最大值
        int max = 0;
        for(int x=1; x<arr.length; x++){
            if(arr[x] > arr[max])
                max = x;
        }
        return arr[max];
    }
    /**
    获取一个整形数组中的最小值
    @param arr 接收一个int类型的数组。
    @return 会返回一个该数组中最小值
    */
    public static int getMin(int[] arr){//获取最小值
        int min = 0;
        for(int x=1; x<arr.length; x++){
            if(arr[x] < arr[min])
                min = x;
        }
        return arr[min];
    }
    /**
    给int数组中的数据进行选择排序
    @param arr 接收一个int类型的数据
    */
    public static void selectSort(int[] arr){//选择排序
        for(int x=0; x<arr.length-1; x++){
            for(int y=x+1; y<arr.length; y++){
                if(arr[x] > arr[y]){
                    swap(arr,x,y);
                }
            }
        }
    }
    /**
    给int数组中的数据进行冒泡排序
    @param arr 接收一个int类型的数据
    */
    public static void bubbleSort(int[] arr){//冒泡排序
        for(int x=0; x<arr.length-1; x++){
            for(int y=0; y<arr.length-x-1; y++){
                if(arr[y] > arr[y+1]){
                    swap(arr,y,y+1);
                }
            }
        }
    }
    /**
    给数组中元素进行位置的置换
    @param arr 接收一个int类型的数值
    @param a 要置换的位置
    @param b 要置换的位置
    */
    private static void swap(int[] arr, int a, int b){//交换数据
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
    /**
    用于打印数组中的元素,打印形式是:[element1,element2,...]
    */
    public static void printArray(int[] arr){//打印数组
        System.out.print("[");
        for(int x=0; x<arr.length; x++){
            if(x! = arr.length-1)
                System.out.print(arr[x]+", ");
            else
                System.out.print(arr[x]+"]");
        }
    }
}

静态代码块

静态代码块的格式

static{
    静态代码块中的执行语句;
}

静态代码块的特点

  • 随着类的加载而执行,只执行一次,并优先于主函数。
  • 用于给类进行初始化。
class StaticCode{
    static {
        System.out.println("a");
    }
}
class StaticCodeDemo{
    static{
        System.out.println("b");
    }
    public static void main(String[] args){
        new StaticCode();
        new StaticCode();
        System.out.println("over");
    }
    static{
        System.out.println("c");
    }
}
//...java StaticCodeDemo
//执行结果:b c a over

主函数

主函数的固定格式

public static void main(String[] args){
}

主函数的定义

  • public:代表着函数的访问权限是最大的。
  • static:代表着主函数随着类的加载就已经存在了。
  • void:主函数没有具体的返回值。
  • main:不是关键字,但是是一个特殊的单词,可以被jvm识别
  • (String[] args):函数的参数,参数类型是一个数组,该数组中的元素是字符串。(字符串类型的数组)

主函数的作用

  • 主函数是一个特殊的函数。作为程序的入口,可以被jvm识别调用。
  • jvm在调用主函数时,传入的是new String[0]

单例设计模式

什么是设计模式

  • 设计模式:解决某一类问题最行之有效的方法。Java中有23种设计模式。
  • 单例设计模式:解决一个类在内存中只存在一个对象。

保证对象唯一

  1. 为了避免其他程序过多建立该对象,先禁止其他程序建立对象。
  2. 还为了让其他程序访问该对象,只好在本类中,自定义一个对象。
  3. 为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

代码实现上述三步

  1. 将构造方法私有化。
  2. 在类中创建一个本类对象。
  3. 提供一个方法可以获取到该对象。
class Single{
    private Single(){}
    private static Single s = new Single();
    public static Single getInstance(){
        return s;
    }
}
class SingleDemo{
    public static void main(String[] args){
        Single ss = getInstance();
    }
}

单例设计模式的使用时机

  • 对于事物该怎么描述,还怎么描述。当需要将该事物的对象保证在内存中唯一时,就将以上三步加上即可。

    //一种实现方式,这种实现方式用的多,定义单例设计模式,建议使用该方式
    //这个是先初始化对象,称为:饿汉式
    //Single类一进内存,就已经创建好了对象。
    class Single{
        private Single(){}
        private static Single s = new Single();
        public static Single getInstance(){
            return s;
        }
    }
    
    //另一种实现方式
    //对象是方法被调用时,才初始化,也叫做对象的延时加载,称为:懒汉式
    //Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。
    class Single{
        private static Single s = null;
        private Single(){}
        public static Single getInstance(){
            if(s==null)
                s = new Single;
            return s;
        }
    }
    //以上两种实现形式都可以!
    

面向对象

原文:https://www.cnblogs.com/yxc-160206/p/13200152.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!