• Java_类与对象


    面向过程指的是只完成自己所需要的操作,但是这种设计缺少可维护性。e.g. 造一辆车,零件全是自己造的。;

    面向对象指的是一种组件化(模块化)设计。方便进行代码的局部维护。但是设计上的要求规范比较多。也就是说模块化的设计最重要的是标准,以及项目的整体的把控。

    面向对象里面分为以下几个特点:

      封装性:保护内部的操作对外部不可见;

      继承性:相当于一代代传承;

      多态性:在一个范围内的定义的改变;

    类的组成:属性(变量)、方法(此方法不是在主类中定义,不由主方法直接调用,不加static);

    范例:定义一个类

    Class Person{

      String name;

      int age;   //定义两个属性(变量)

      public void tell() {

        System.out.println(name + " , " + age );

      }

    }

    类本身不能直接使用,所有的类必须通过对象才能使用;由于类属于引用数据类型(有内存关系),所以对象的定义语法有两种:

      声明并实例化对象:类名称 对象名称 = new 类名称();

      分步进行:

        声明对象:类名称 对象名称 = null;

        实例化对象:对象名称 = new 类名称();

    引用数据类型在使用之前必须开辟空间,而基本数据类型可以直接赋值,开辟新的内存空间的关键字为new;

    一旦有了对象后,就可以用对象来实现类中属性和方法:

      调用属性:实例化对象.属性名称;

      调用方法:实例化对象. 方法();

    范例:定义对象并使用:

    Class Person{

      String name;

      int age;   //定义两个属性(变量)

      public void tell() {

        System.out.println(name + " , " + age );

      }

    }

    public class TestDemo{

      public static void main(String args[]){

        Person per = new Person(); //声明并实例化对象

        per.name = "张三" ;

        per.age = 30;

        per.tell();

      }

    }

    类属于引用数据类型,因此必须为其进行内存分析。

    两个内存空间概念:

      堆内存空间(Heap):保存的是对象中具体的属性信息;

      栈内存空间(Stack):保存的堆内存的地址数值,假设保存在栈内存的是对象名称。按照以上分析得出以下内存关系图:

    引用数据使用与C语言一样。

    分步声明和实例化对象内存分析:

    Class Person{

      String name;

      int age;   //定义两个属性(变量)

      public void tell() {

        System.out.println(name + " , " + age );

      }

    }

    public class TestDemo{

      public static void main(String args[]){

        Person per = null; //声明对象

        per = new Person(); //实例化对象

        per.name = "张三" ;

        per.age = 30;

        per.tell();

      }

    }

    注意:关于引用数据类型操作存在的重要问题:

      理论上当对象开辟堆内存(实例化对象)那么属性才会进行内存分配,那么如果使用了没有实例化的对象呢?这个时候程序编译没问题。

    此时返回的是“NullPointerException”异常,翻译:空指向异常,这个异常只有引用数据类型会出现,原因只有一点:使用了没有开辟内存空间的引用对象。

     初步分析引用传递

     引用传递是在引用数据类型上所用的一个操作定义,是Java精髓,操作与C的指针相同。针对内存进行操作。

    换到程序中就是一块堆内存空间可以同时被多个栈内存所指向。

    范例:引用传递

    Class Person{

      String name;

      int age;   //定义两个属性(变量)

      public void tell() {

        System.out.println(name + " , " + age );

      }

    }

    public class TestDemo{

      public static void main(String args[]){

        Person perA = new Person();  

        perA.name = "张三" ;

        perA.age = 30;

        Person perB = perA;  //引用传递

        perB.name = "李四" ;

        perA.tell();

      }

    }

    结果:李四 30

    以上是采用了声明对象的方式进行了引用数据类型的接收,那如果两个对象都已经明确实例化并设置内容了呢?

    范例:

    Class Person{

      String name;

      int age;   //定义两个属性(变量)

      public void tell() {

        System.out.println(name + " , " + age );

      }

    }

    public class TestDemo{

      public static void main(String args[]){

        Person perA = new Person();  

        Person perB = new Person();  

        perA.name = "张三" ;

        perA.age = 30;

        perB.name = "王五" ;

        perB.age = 10;

           perB = perA;  //引用传递

        perB.name = "赵六 ;

        perA.tell();

      }

    }

    结果:赵六 30

    通过以上的分析,应该可以发现:

      使用关键字new永恒可以开辟新内存空间,堆内存保存的就是属性

      栈内存只能够保存一块堆内存的使用地址

      引用传递的本质在于同一块堆内存空间可被不同的栈内存所指向

      发生引用传递时,如果操作的栈内存原本有堆内存指向,那么改变对空间就意味着改变内存指向

      如果某一块堆内存没有任何栈内存所指向,那么此空间将成为垃圾空间,所有的垃圾空间会自动的GC(垃圾收集器 Garbage Collector)回收并且释放,由于垃圾回收时间不确定所以少产生垃圾空间。

      如果想产生垃圾,除了改变引用之外,也可以设置为空null。perB = null;那就表示放弃原本的指向,变为一个没有指向的栈内存。

  • 相关阅读:
    动态规划:DAG-嵌套矩形
    动态规划:LCIS
    动态规划&字符串:最长公共子串
    动态规划:LCS
    动态规划:状压DP-斯坦纳树
    动态规划:数位DP
    JavaScript 正则表达式
    JavaScript 类型转换
    JavaScript typeof, null, 和 undefined
    JavaScript if...Else 语句
  • 原文地址:https://www.cnblogs.com/lonske/p/8666862.html
Copyright © 2020-2023  润新知