1、面向对象概念
2、面向对象特性
知识点:
- 掌握类与对象的定义结构;
- 掌握对象的内存分配。
可以使用 “ class 类名{}” 的语法结构完成:
类的使用 —— 在主类中使用
对象的定义有两种方法:
引用数据类型与基本数据类型最大的不同在于需要内存空间的开辟及使用,所以关键字 new 的作用就是开辟内存空间,即只要是想使用引用类型,必须使用关键字 new 来开辟内存空间。
两块内存空间的概念:
举例:下面这三行代码,对应的内存空间
Book bk = new Book();
bk.title = "Java 开发";
bk.price = "89.9";
任何情况下只要看见了关键字 new,都表示要开辟新的堆内存空间,一旦堆内存空间开辟了,里面就一定会有类中定义的所有的属性,属性的值为其对应数据类型的默认值。
对象定义除了可以用一行语句之外,还可以分步完成。
举例:分步的方式实例化对象
Book bk = null;
bk = new Book();
bk.title = "Java 开发";
bk.price = "89.9";
这两种方法结果上没有区别,但是内存图是不一样的,如上图所示。
那分步完成和一句代码完成有什么区别呢?
开辟了堆内存的对象称为实例化对象。那么如果使用了没有实例化的对象,如下所示:
Book bk = null;
bk.title = "Java 开发";
由于使用了没有实例化对象,所以在程序运行时出现了 “NullPointerException” ,此类异常只要是引用数据类型都可能会出现。
在所有的引用分析里,最关键的还是在于关键字 new,一定要注意的是,每一次 new 都是生成新的堆内存空间,所以如果你的代码里声明了两个对象,并且使用了关键字 new 为每个对象开辟了堆内存空间,那么一定是各自占有各自的堆内存空间,并且不会互相影响。
举例:声明两个对象
Book bookA = new Book();
Book bookB = new Book();
bookA.title = "Java 开发";
bookA.price = "89.8";
bookB.title = "JSP 开发";
bookB.price = "69.8";
引用类型的使用 —— 引用类型的传递举例
Book bookA = new Book();
bookA.title = "Java 开发";
bookA.price = "89.8";
Book bookB = bookA; // 这里就是引用传递。
bookB.price = "69.8";
bookA 和 bookB 指向的是同一块堆内存,所以任何一个对象修改了堆内存中的数据后,都会影响其他对象。在引用的操作过程中,一块堆内存可以同时被多个栈内存所指向,但是反过来,一块栈内存只能保存一块堆内存空间的地址。
继续观察引用传递
Book bookA = new Book();
Book bookB = new Book();
bookA.title = "Java 开发";
bookA.price = "89.8";
bookB.title = "JSP 开发";
bookB.price = "69.8";
Book bookB = bookA; // 这里就是引用传递。
bookB.price = "100.1";
通过内存的分析可以发现,在引用数据类型关系里面,一块没有任何栈内存指向的堆内存空间就将成为垃圾,所有的垃圾会不定期的被垃圾回收机(GC)进行回收,回收之后会释放掉其所占用的空间。
虽然在 Java 里面支持了自动的垃圾收集处理,但是在代码的开发过程中应该尽量的减少垃圾空间的产生。
1、声明对象指的是未开辟堆内存的对象,如果直接使用此对象会出现 “NullPointerException”;
2、对象可以通过关键字 new 来进行堆内存空间的开辟,有了堆内存引用的对象才称为实例化对象;
3、堆内存保存的是对象中所有属性的内容,而栈内存保存的是堆内存的地址数值(为简单理解才称栈内存保存的是对象名称);
4、垃圾空间指的未被任何栈内存指向的堆内存空间,会被 GC 不定期进行回收;
5、一定要熟练掌握上面的内存图的分析方法,并且可以在脑袋中绘制内存图。
所有在类中定义的属性都要求使用 private 声明,这样属性只能在本类可以访问;如果属性要被外部的类访问,则需要定义相应的 setter、getter 方法。
Book book = new Book();
构造方法的核心作用:在类对象实例化的时候设置属性的内容。
但是这个默认值只有在构造方法执行完成后才会设置,而构造方法是属于整个对象构造过程的最后一步,即是留给用户处理的步骤。
class Book{
private String title = "Java 开发";
public Book(){}
}
本程序之中,只有在整个构造都完成之后,才会真正将 “Java 开发” 这个字符串的内容赋值给 title,在构造方法执行执行之前,title 都是其对应数据类型的默认值。
没有栈指向的对象就称为匿名对象。
new Book("Java 开发",89.8).getInfo();
但是匿名对象由于没有其他对象对其进行引用,所以只能使用一次,一次使用之后该对象就会成为垃圾,等待被回收。
第一个代码模型的目标:
实现简单 Java 类
这种功能的类在开发之中称为简单 Java 类,因为这些类里面不会包含有过于复杂的程序逻辑。
对于简单 Java 类而言,现在给出它的第一种开发要求:
class Employee{
private int empId;
private String name;
private String job;
private double salary;
Employee(){}
Employee(int id, String name, String job,double salary){
this.empId = id;
this.name = name;
this.job = job;
this.salary = salary;
}
public void setEmpNo(int id){
this.empId = id;
}
public void setName(String name){
this.name = name;
}
public void setJob(String job){
this.job = job;
}
public void setSalary(double salary){
this.salary = salary;
}
public int getEmpId(){return this.empId;}
public String getName(){return this.name;}
public String getJob(){return this.job;}
public double getSalary(){return this.salary;}
public String getInfo(){
return "雇员编号: " + this.empId + "\n" +
"姓 名: " + this.name + "\n" +
"职 位: " + this.job + "\n" +
"薪 资: " + this.salary + "\n";
}
}
public class EmployeeTest{
public static void main(String[] args){
Employee emp = new Employee(456, "Alice", "test-devloper", 1000.0);
emp.setJob("QA");
System.out.println(emp.getInfo());
}
}
类中提供的所有 setter、getter 方法可能某些操作不会使用到,但是依然必须提供。所有的 setter 方法除了具备有设置属性的内容之外,也能修改属性的内容。
简单 Java 类是日后进行整个项目开发的千分之一的组成部分,也是最为重要的组成部分。上面的代码要写的很熟练。