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;那就表示放弃原本的指向,变为一个没有指向的栈内存。

原文地址:https://www.cnblogs.com/lonske/p/8666862.html