什么是面向对象:
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一个事物在整个解决问题的步骤中的行为。面向对象程序设计中的概念主要包括:对象、类、数据抽象、继承、动态绑定、数据封装、多态性、消息传递。通过这些概念面向对象的思想得到了具体的体现。
一、对象的创建:
1、在类定义结束之后,可以使用这个类“模板”来创建“对象”;
格式:new 类名();
public class Student {
//成员变量
String name;
int age;
//成员方法
public void eat(){
System.out.println("吃饭饭");
};
public void sleep(){
System.out.println("睡觉觉");
}
public void learn(){
System.out.println("学习");
}
}
public class Demo02Student {
public static void main(String[] args) {
//创建
Student stu = new Student();
//使用成员变量
System.out.println(stu.name); //null
stu.name = "赵丽颖";
System.out.println(stu.name); //赵丽颖
//使用成员方法
stu.learn();
stu.eat();
stu.sleep();
}
}
注意事项:
1、如果成员变量没有进行赋值,那么他会有一个默认值,规则和数组的一样。
数据类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0 |
boolean | false |
char | \u0000 |
引用类型 | null |
2、成员变量定义在方法的外边,类的里边。
3、成员方法不能使用static修饰
4、对于boolean类型,getter方法一定要写成isXxx
2、局部变量和成员变量的区别:
1、定义的位置不同:局部变量在方法内部,成员变量在类内部
2、作用范围不一样:局部变量作用于方法内部,成员变量作用与类的内部
3、默认值:局部变量没有默认值,必须手动赋值;成员变量有默认值。
4、内存位置不同:局部变量:栈内存;成员变量:堆内存
5、生命周期不同:局部变量:随着方法的进栈而诞生,方法的出栈而消失;成员变量:随着对象的诞生而诞生,随着对象内垃圾回收而消失
二、对象的内存图解
1、JVM虚拟机的内存管理
1、程序计数器:当前线程所执行的字节码的行号指示器(线程私有的内存)
2、java虚拟机栈:
①、概念:描述的是java方法执行的内存模型,是每个方法在执行的时候会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用知道完成的过程,就对应一个栈帧从入栈到出栈的过程。
②、特点:线程私有,生命周期和线程相同。这里会出现两种异常:StackOverflowError异常:若线程请求的深度大于虚拟机所允许的深度。
OutOfMemoryError异常:若虚拟机可以动态扩展,如果扩展是无法申请到足够的内存。
3、本地方法栈:
①、概念:与虚拟机栈发挥的作用相似,区别是java虚拟机栈为执行java方法服务,本地方法栈是为本地方法服务。
②、特点:线程私有,也会抛出StackOverflowError异常和OutOfMemoryError异常
4、java堆
①、概念:是被线程共享的一块区域,在虚拟机启动时创建
②、特点:线程贡献,存放的是对象示例(所有的对象实例和数组),GC管理的主要区域,可以处于物理上不连续的内存空间。
5、方法区:
①、概念:存储已被虚拟机加载的类信息、常量、静态变量,即时编译器编译后的代码等数据
②、特点:线程共享,抛出OutOfMemory异常,当方法区无法满足内存分配需求时。
2、java虚拟机内存管理简图
public class StudentTest{
public static void main(String[] args){
int i = 10;
Student s1 = new Student();
}
}
注意:
1、Java中只能通过引用去访问堆内存中的对象,也就是s1。
2、其实这里的String也是一个类,所以zhangsan是一个字符串对象的内存地址,即应该存储在方法区的字符串常量池中。
三、构造方法
1、概念
构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法,以及对象属性的初始化操作。
格式:
public 类名称(参数类型 参数名称){
方法体
}
注意事项:
1、构造方法的名称必须和所在的类名称完全一样,大小写也要一样
2、构造方法不要写返回值类型,连void都不写
3、构造方法不能return一个具体的返回值
4、如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数,方法体什么都不做
public Student(){}
5、一旦编写了至少一个构造方法,那么编译器将不再赠送
6、构造方法也是可以进行重载(方法名称相同,参数列表不同)的
2、一个标准的类
一个标准的类通常要满足下面四个组成部分:
1、所有的成员变量都要使用private关键字修饰
2、为每个成员便改良编写一对getter/setter方法
3、编写一个无参数的构造方法
4、编写一个全参数的构造方法
这样的标准类也叫Java Bean
public class Student {
private String name;//姓名
private int age;//年龄
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
一些总结:
1、什么是封装
信息隐蔽,利用抽象数据类型(将数据对象、数据对象之间的关系和数据对象的基本操作封装在一起的一种表达方式,它和工程中的应用是一致的)将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外的接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交互。如:“鼠标”,“数码相机”。
2、为什么setter和getter方法不能带static关键字
带有static的方法是静态方法,不需要创建对象,通过“类”来调用。对于没有static关键字的方法被称为实例方法,这些方法的执行必须要先创建对象,然后通过“引用”来调用;而getter与setter方法是需要去访问对象内部的属性,所以不能加static关键字。