前言
首谈Java,了解了面向对象的三大特性以及对象在内存中的概况.熟悉了基本Java概念.总结了private实现封装及this,static关键字的用法
面向对象编程之类与对象(上)
1.面向对象的三大特性
① 封装性:
封装性就是指将一个客观的事物封装成抽象的类,这个类具有自己的属性以及方法,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.简而言之就是,内部操作对外部而言不可见(保护性)
② 继承性:
继承是指这样一种能力: 他可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行拓展
③ 多态性:
所谓多肽就是指一个类实例的相同方法在不同情形下有不同的表现形式.多态机制使具有不同内部结构的对象可以共享想通过的外部接口
与面向对象语言相比,面向过程的语言缺少了代码的可重用性
2.对象内存分析
此处可以暂时将Java内存分为两部分,一部分称为栈,一部分称为堆
栈 : 在栈中存放的是局部变量(包括在编译期可知的各种基本数据类型,对象引用–>即堆内存的地址,可以暂时理解为对象的名称),Java栈是与线程对应起来的,每当创建了一个线程,JVM就会为这个线程创建一个对应的Java栈!
堆 : 保存的是真正的信息,即对象的属性信息
3.NullPointerException 空指针异常错误
这是一个运行时异常,编译阶段是检查不出来的. 造成这个异常的原因就是对象引用为空值.所以以后一定要注意,对象(引用数据类型)必须在实例化后调用.只有引用类型(数组、类、接口)才会产生此类异常。以后出现此类异常,就根据出错位置查看引用类型变量是否初始化
4.对象引用的概念
1 | Persion per1 = new Persion(); |
以上代码,本来per1和per2都有自己所指向的堆空间,但是当把per2赋值给per1后,per1和per2都指向了per2原本指向的堆内存空间,此时per1原本指向的堆内存空间就再也没有引用指向他了,这块堆内存空间也就成了一块垃圾空间,GC会不定期的进垃圾空间的回收
5.使用private对属性进行封装
使用private修饰的属性只能使用setter和getter方法来进行访问
setter: 主要用于进行属性内容的设置和修改
getter:主要用于属性内容的取得
private实现封装的最大特征在于: 只允许本类进行访问,不许允外部类进行私有属性或方法的访问
6.类的设计原则
属性都要被private修饰,如果想要外部类能够访问属性,就设置setter和getter方法
7.构造方法
所谓构造方法就是使用关键字new实例化对象时来进行调用的操作方法.对于构造方法的定义,要遵循以下原则:
- 构造方法的名字必须与类名相同
- 构造方法没有返回值类型声明
- 每个类中一定至少存在一个构造方法(如果没有明确声明,则系统会默认生成一个无参的构造方法)
编译器怎么区分普通方法和构造方法?
- 属性是在堆开辟空间的时候定义的
- 构造方法是在new之后进行调用的
- 普通方法是在对象创建完成,内存空间分配完毕之后调用的
所以,编译器是根据程序的不同结构来区别普通方法和构造方法的,这也是构造方法为什么没有返回值类型的原因,这样编译器才能更高的区别
若类中定义了构造方法,则默认的构造方法不在生成
构造方法和对象内存分配几乎是同时完成的.因此我们可以使用构造方法来对对象进行初始化,避免了多次使用setter方法
构造方法也是可以重载的
8. 匿名对象
1 | new Persion(18,"张三").toString(); |
由于匿名对象没有对象引用,所以匿名对象只能使用一次,之后就变为了垃圾空间
9.this关键字
this关键字的三种用途
1. this调用本类属性: 在一个类中调用此类中的属性必须使用this关键字,例如构造器中调用属性1
2
3
4public Persion(String name,int age){
this.name = name; //此时必须使用this关键字,否则是不能够成功赋值的
this.age = age;
}
2. this调用本类方法
this调用本类方法包括调用普通方法和调用构造方法两种
1.this调用本类普通方法:
在本类方法或者构造方法中调用本类的某个方法也是要加上this,虽然这里不加也能运行,但是最好加上让自己能够更加清晰的理解1
2
3
4
5public Persion(String name,int age){
this.print();
this.name=name;
this.age=age;
}
2.this调用本类构造方法
在Java中支持构造方法的互相调用,直接使用 this() 就是调用构造器1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48class Persion{
private int age;
private String name;
public Persion(){
System.out.println("创建一个新的对象");
}
public Persion(int age){
System.out.println("创建一个新的对象");
this.age = age;
}
public Persion(int i, String name) {
System.out.println("创建一个新的对象");
this.setAge(i);
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int i) {
if(i>=0 && i<=100){
this.age = i;
}else{
this.age =0;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private void print(){
System.out.println("gaga");
}
public void getInfo(){
System.out.println("姓名: "+this.age+" 姓名: "+this.name);
}
}
我们看到如果一个类中一个构造方法这样的写会有很多的重复代码,十分的低效,所以,我们使用this关键字在不同构造器之间进行相互的调用,修改如下1
2
3
4
5
6
7
8
9
10
11
12
13public Persion(){
System.out.println("创建一个新的对象");
}
public Persion(int age){
this();
this.age = age;
}
public Persion(int age, String name) {
this(age);
this.name = name;
}
使用this调用本类构造器需要注意:
- this调用构造方法必须放在构造方法的首行
- 使用this调用构造方法时,必须留有出口
3. this表示当前类的对象
只要对象调用了当前类的方法,this就代表当前类的对象
10.static关键字
stati修饰属性
static修饰的属性称为静态属性,普通的属性都是存放于堆中且每个类所创建的对象都单独享有他们的属性,他们随着对象的创建而生成于堆中.而被static修饰过的属性是存放在全局数据区的,所有类的对象可以共享这个数据,他也不受对象创建所约束,在类加载的时候此数据就已经被加载进内存空间
- 访问static属性(类属性)应使用 类名称.属性名
- 所有非static属性(实例变量)必须在对象实例化后使用,而static属性不受对象实例化控制
- 一般想要描述共享属性的时候就使用static关键字
static修饰方法
static修饰的方法可以直接通过类名.方法名来进行调用
两点说明:
- 所有的static方法不可以调用非static调用的方法和属性
- 所有的非static方法可以调用static方法和属性
- 使用static定义方法只有一个目的:某些方法不希望受到对象的控制,即可以在没有实例化对象之前的时候执行(广泛存在于工具类)