分析类与对象
1、学习内容
1、封装的目的;
2、封装的实现;
3、构造方法的定义语法以及调用时机;
4、匿名对象的基本使用;
2、具体内容
2.1、封装的目的和实现
我们先观察一段代码:
class Book{
String title;
int price;
public void getInfo(){
System.out.println("图书名称:"+title+"图书价格"+price);
}
}
public class TestDemo{
public static void main(String args[]){
Book book=new Book();
book.title="java开发";
book.price=-23;
book.getInfo();
}
}
- 以上的代码之中的没有任何的语法错误,但是却存在业务逻辑上的错误,书的价格为负数,造成此问题的核心是:对象可以在一个类的外部直接访问属性,需要将Book类中的属性设置为对外不可见。
修改之后的程序:
class Book{
private String title;
private int price;
public Book(String title,int price){
this.title=title;
this.price=price;
}
public void getInfo(){
System.out.println("图书名称:"+title+"图书价格"+price);
}
}
public class TestDemo{
public static void main(String args[]){
Book book=new Book("java",23);
book.getInfo();
}
}
针对属性的定义:所有类中的定义的属性都要求使用private声明,如果属性需要被外部所使用,按照要求定义相应的setter,getter方法,以String title为例。
-
setter方法主要是设置内容,public void setTitle(Stirng t),有参;
-
getter方法主要是取得属性的内容:public String getTitle().无参。
范例:为Book类中的封装属性设置setter、getter方法class Book{ private String title; private int price; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getPrice() { return price; } public void setPrice(int price) { if(price>0){ this.price=price; }else{ } } public void getInfo(){ System.out.println("图书名称:"+title+"图书价格"+price); } } public class TestDemo{ public static void main(String args[]){ Book book=new Book(); book.setPrice(-23); book.setTitle("java程序"); book.getInfo(); } }
在开发中验证是由其他辅助的代码完成的,而在实际的开发中,setter往往是简单的设置数据,getter往往是简单的取得数据而已。
2.2、构造方法的使用
class Book{
public Book(){
System.out.println("*********");
}
}
public class TestDemo{
public static void main(String[] arg){
Book book=null;//声明对象,没有开辟堆内存空间
book=new Book();//实例化对象,开辟堆内存空间
}
}
通过以上代码可以发现,所有构造方法都在对象使用关键字new实例化的时候默认调用。
构造方法与普通方法的最大区别:
- 构造方法是在实例化对象(new)的时候只被调用一次
- 普通方法是在实例化对象产生后可以随意调用多次
既然构造方法是在对象实例化的时候使用的,这样的做法有什么用处?
class Book{
private String title;
private int price;
public Book(String title,int price){
this.title=title;
setPrice(price);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
if(price>0){
this.price=price;
}else{
}
}
public void getInfo(){
System.out.println("图书名称:"+title+"图书价格"+price);
}
}
public class TestDemo{
public static void main(String args[]){
// 在实例化对象的同时将所需要的属性传递到对象的构造方法里
Book book=new Book("java程序",34);//使用默认的构造方法
book.getInfo();
}
}
构造方法的核心作用是:在类对象实例化的时候设置对象的初始化内容,或者说构造方法是为属性初始化准备的。
如果一个类中已经明确的定义了一个构造方法,那么不会自动生成默认的构造方法,一个类中至少保留一个构造方法,构造方法可以重载,构造方法重载时,参数个数或类型不同即可。
范例:构造方法重载
class Book{
private String title;
private int price;
public Book(String title){
this.title=title;
System.out.println("有一个参数的构造方法");
}
public Book(String title,int price){
this(title);
this.price=price;
System.out.println("有两个参数的构造方法");
}
public void getInfo(){
System.out.println("图书名称:"+title+"图书价格"+price);
}
}
public class TestDemo{
public static void main(String args[]){
Book book=new Book("java程序",34);
book.getInfo();
}
}
在进行构造方法的重载时:请按照参数的个数升序编写,这样好看(呵呵)。
- 问题:在定义一个类的时候可以为属性直接设置默认值,但是这个默认值只有在构造执行完后才会设置,而构造方法是属于整个对象构造过程的最后一步,即:是留给用户处理的步骤。
在对象实例化的过程中,一定会经历类的加载、内存的分配、默认值的设置、构造方法。
2.4、匿名对象
在上述程序中,只有整个构造方法都完成之后,才会真正将“java开发”这个字符串的内容设置给title属性,在没有构造之前title都是其对应属性的默认值。
那么有了构造方法的概念,实际上就可以依照此方式使用匿名对象,之前定义都是有名对象,所有的对象都给了一个名字,但是这个名字真正使用的时候调用的是堆内存空间,即:真实的对象信息保存在堆内存之中,那么没有栈指向的对象就称为匿名对象。
class Book{
private String title;
private int price;
public Book(String title,int price){
this.title=title;
this.price=price;
}
public void getInfo(){
System.out.println("书名:"+title+","+"价格"+price);
}
}
public class TestDemo{
public static void main(String args[]){
new Book("java",33).getInfo();
}
}
- 但是匿名对象由于没有其它对象进行引用,所以只能只用一次,一次之后该对象空间将成为垃圾,等待回收。
3、总结
- 封装性就是保证内部的定义被外部不可见;
- 所有属性都必须使用private封装,封装后的属性如果要被外部所访问,要定义setter,getter方法;
- 构造方法的定义要求:方法名称与类名称相同,无返回值声明;
- 构造方法是在类对象使用关键字new实例化对象的时候被默认调用的,一个类中至少保留一个构造方法,无自己定义的构造方法,则程序会有默认的构造方法;
- 构造方法重载时,考虑参数的个数和类型即可,且构造方法只使用一次;
- 对象信息保存在堆内存之中,那么没有栈指向的对象就称为匿名对象。