Java中的类与对象
本文借鉴于Java面向对象之类与对象(一),有所改动
1.面向对象简介
Java是一个面向对象的语言。对程序员来说,面向对象设计意味着要注意应中的数据和操纵数据的方法(method),而不是严格地用过程来思考。它有三个主要特征:
- 封装性:内部的操作对外而言不可见;当内部的操作都不可以直 接使用的时候才是安全的。
- 继承性:在已有结构的基础上继续进行功能的扩充。
- 多态性:是在继承性的基础上扩充而来的概念,指的是类型的转换处理。
在进行面向对象的开发中一般有三个步骤:
- OOA:面向对象分析
- OOD:面向对象设计
- OOP:面向对象编程
2.类与对象简介
在一个面向对象的系统中,类(class)是数据和操作数据的方法的集合。数据和方法一起描述对象(object)的状态和行为。每一对象是其状态和行为的封装。
类是按一定体系和层次安排的,使得子类可以从超类继承行为。在这个类层次体系中有一个根类,它是具有一般行为的类。Java程序是用类来组织的。
类是对一类“事物”的属性与行为的抽象,而对象则是对抽象的类的具体化,所以先有类再有对象。
例如:学校里的学生,他们都有一个共同的身份——学生。学生之间彼此是不同的,区别这些不同则是根据各自的属性:姓名、班级、学号、成绩等等。此外,学生都有共同的行为——学习以及其他。
3.Java中的类与对象
3.1 类的定义
Java中类主要由属性和方法构成。属性是一个个具体的变量,方法是可以重复执行的代码。
定义一个类的语法:
class 类名称 {
属性1;
属性2;
属性n...;
方法1(){}
方法2(){}
方法n(){}...
}
范例:
class Person{
public String name;
public int age;
public void work()
{
System.out.println(name+"在工作!");
}
public void age()
{
System.out.println(name+age+"岁!");
}
}
有了类我们就可以创建对象。
3.2 对象的定义
产生对象的语法:
声明并实例化对象:类名称 对象名称 = new 类名称();
或者分步骤完成
声明对象:类名称 对象名称 = null;
实例化对象:对象名称 = new 类名称();
以上述Person为例,产生一个Person类的对象:
Person p = new Person();
3.3 对象的引用
当获取了实例化对象之后,那么就需要通过对象对类中的属性和方法调用。
此时有两种调用方式:
调用类中的属性:实例化对象.成员属性;
调用类中的方法:实例化对象.方法名称();
当你不对属性值进行设置的时候,则该属性值为对应数据类型的默认值。
String 默认值为:null
int 默认值为:0
范例:使用对象操作类
public class JavaDemo{
public static void main(String args[]){
Person per = new Person(); //声明并实例化对象
per.name = "张三"; //设置属性姓名值
per.age = 18 ; //设置属性年龄值
per.tel(); //进行方法的调用
}
}
3.4 Java中的类、抽象类、接口
抽象类:
- 可以有抽象方法和非抽象方法
- 子类必须实现父类的抽象方法,不必实现父类的非抽象方法
- 非抽象方法需要body,抽象方法不能有body
- 抽象类不能被实例化,即不能有new关键字去产生抽象类的对象
接口:
- 接口的数据成员是public static final的,必须要初始化
- 接口没有构造方法
- 接口中的方法没有body
Java里有什么办法判断一个Class是否为抽象类?
Class a = Class.forName(“A”);
System.out.println(Modifier.isAbstract(a.getModifiers()));
4.对象内存分析
Java中类属于引用数据类型,引用数据类型最大的困难之处在于要进行内存的管理,同时在进行操作的时候也会发生有内存关系的变化。
如果要进行内存分析,那么首先要给出两块最为常用的内存空间:
堆内存: 保存的是对象的具体信息。
栈内存: 保存的是一块堆内存的地址,即:通过地址找到堆内存,而后找到对象内容。
但是为了分析简化起见,简单地理解为对象的名称保存在了栈内存之中。
实例化对象有两种方式:
- 一种是直接声明并实例化对象
- 一种是分布完成实例化对象的操作
范例1:直接声明并实例化
public class JavaDemo{
public static void main(String args[]){
Person per = new Person(); //声明并实例化对象
per.name = "张三"; //设置属性姓名值
per.age = 18 ; //设置属性年龄值
per.tel(); //进行方法的调用
}
}
范例2:先声明再实例化
public class JavaDemo{
public static void main(String args[]){
Person per = null; //声明对象
per = new Person(); //实例化对象
per.name = "张三"; //设置属性姓名值
per.age = 18 ; //设置属性年龄值
per.tel(); //进行方法的调用
}
}
需注意的是所有的对象必须在对象实例化完成之后才可以被引用。
范例3:错误示范
public class JavaDemo{
public static void main(String args[]){
Person per = null; //声明对象
//per = new Person();//将创建实例化的代码注释掉 //实例化对象
per.name = "张三"; //设置属性姓名值
per.age = 18 ; //设置属性年龄值
per.tel(); //进行方法的调用
}
}
代码中只声明了对象而未实例化对象,所以此时无法调用它的属性和方法。
此时会报一个NullPointerException(空指针异常) ,就是 (实例化对象)没有在堆内存开辟后时所产生的问题,并且只有引用数据类型存在有此异常NullPointerException,基本数据类型不存在此异常,此异常将伴随整个开发过程。
5.对象引用传递与垃圾产生分析
类本身属于引用数据类型,那么就牵扯到内存的引用传递。
所谓的引用传递的本质:同一块堆内存空间可以被不同的栈内存指向,也可以更换指向。
范例:定义一个引用传递的分析程序:
public class JavaDemo{
public static void main(String args[]){
Person per1 = new Person(); //声明并实例化对象
Person per2 = new Person(); //声明并实例化对象
per1.name = "张三";
per1.age = 18 ;
per2.name = "李四";
per2.age = 19 ;
Person per2 = per1 ; //引用传递
Person.age = 80 ;
per1.tell() ; //进行方法的调用
}
}
此时已经明确的发生了引用传递,并且也成功的完成了引用传递的处理操作。
下面来观察下内存分配与处理流程:
所谓的垃圾空间指的就是没有任何栈内存所指向的堆内存空间,所有的垃圾将被GC(Garbage Collector、垃圾收集器) 不定期进行回收,并且释放无用内存空间。但是垃圾过多,一定将影响到GC的处理性能,从而降低整体的程序性能,那么在实际的开发之中,对于垃圾的产生应该越少越好。
一个栈内存只能够保存有一个堆内存的地址数据,如果发生更改,则之前的地址数据将从此栈内存中彻底消失。
7.构造器
现在的程序在使用类的时候一般都按照了如下的步骤进行:
- 声明并实例化对象,这个时候实例化对象中的属性并没有任何的数据存在,都是其对应数据类型的默认值
- 需要通过一系列的 setter 方法为类的属性设置内容
不难发现,当属性比较多时,给对象的属性赋值是一件很麻烦的事情。
为了解决这个问题Java专门提供了构造方法,可以通过构造方法实现实例化对象中的属性初始化处理(只有在关键字 new 的时候才会使用构造方法)。
在Java程序里面构造方法的定义要求如下:
- 构造方法名称必须与类名称保持一致;
- 构造方法不允许设置任何的返回值类型,即没有返回值定义;
- 构造方法是在使用关键字 new 实例化对象的时候自动调用的,根据输入的参数不同调用不同的构造方法。
- 一旦构造器被重写,默认的构造器就会失效,需要重写一个无参的构造器。
范例:定义构造方法
class Person{ //定义一个类
String name ; //人员的姓名
int age ; //人员的年龄
//方法名称与类名称相同,并且无返回值定义
public Person(String naem,int age){ //定义有参构造
this.name = name; //为类中的属性赋值(初始化)
this.age = age ; //为类中的属性赋值(初始化)
}
//定义一个方法
public void tell(){
System.out.println("姓名:" + this.name + "、年龄:" + age);
}
}
public class JavaDemo{
public static void main(String args[]){
Person per = new Person("张三",18); //声明并实例化对象
per1.tell() ; //进行方法的调用
}
}
参考资料:
- https://www.cnblogs.com/wvae/articles/9682991.html
- https://blog.csdn.net/zhao_miao/article/details/83187576
- https://blog.csdn.net/xingkongbaobei/article/details/38856655
- https://blog.csdn.net/riverflowrand/article/details/52733995