面向对象与封装
堆、栈、方法区
- 栈:方法只要执行,会压栈。(局部变量)
- 堆:new出来的对象都在堆中。垃圾回收器主要针对。(实例变量)
- 方法区:类的信息,字节码信息,代码片段。(静态变量)
- 注意:方法的代码片段放在方法区,但是方法执行过程当中需要的内存在栈中。
当我们采用面向对象的方式贯穿整个系统的话,涉及到三个术语:
- OOA:面向对象分析(Object-Oriented Analysis)
- OOD:面向对象设计(Object-Oriented Design)
- OOP:面向对象编程(Object-Oriented Programming)
- 整个软件开发的过程,都是通过OO进行贯穿的。
- 实现一个软件的过程:分析(A)–>设计(D)–>编程§
- leader 领导/经理/组长
- team 团队
- PM 项目经理(整个项目的监管人) Project Manager
面向对象包括三大特征:
- 封装、继承、多态
- 有了封装,才有继承,有了继承,才能说多态。
- 任何一个面向对象的编程语言都包括这三个特征,例如:python、java
类与对象的概念:
- 类:类在现实世界当中是不存在的,是一个模板,是一个概念。是人类大脑思考抽象的结果。类代表了一类事物。
- 在现实世界当中,对象A与对象B之间具有共同特征,进行抽象总结出一个模板,这个模板被称为类。
- 对象:对象是实际存在的个体。现实世界当中实际存在。
- 注意:在java语言中,要想得到“对象”,必须先定义“类”,“对象”是通过“类”这个模板创造出来的。通过类创建对象的过程我们可以称为“创建”,也可以称为“实例化”,“对象”还有一个名称“实例/instance”。多个对象具有共同特征,进行思考总结抽取共同特征的过程称为“抽象”。
- 类–【实例化】->对象(实例)
- 对象–【抽象】->类
- 类描述的是对象的共同特征。
- 共同特征例如:身高特征,这个身高特征在访问的时候,必须先创建对象,通过对象去访问这个特征。因为这个特征具体的某个对象上之后,值不同。有的对象身高1.80,有的对象身高2.80。
- 一个类主要描述什么信息呢?
- 一个类主要描述的是 状态 + 动作。
- 状态信息:名字、身高、性别、年龄
- 动作信息:吃、唱歌、跳舞、学习
- 状态–> 一个类的属性 动作–> 一个类的方法
- 类{
属性; // 描述对象的状态信息 方法; // 描述对象的动作信息 } - 注意:状态和动作当具体到某个对象上之后,发现最终的结果可能不一样。对象和对象之间有共同特征,但是具体到对象之后有数据的差异。
怎么定义一个类,语法格式是什么?
为什么属性是“以”变量的形式存在的?
- 假设我们要描述一个学生:
- 学生包括哪些属性:
- 学号: 001
- 姓名:“张三”
- 性别:‘男’ (true/false)
- 住址:“北京”
- 答案:是因为属性对应的是“数据”,数据在程序中只能放到变量中。
- 结论:属性其实就是变量。
- 变量根据出现位置进行划分:
- 方法体当中声明的变量:局部变量。
- 方法体外声明的变量:成员变量。(这里的成员变量就是“属性”)
在语法级别上是怎么完成对象创建的呢?
- 类名 变量名 = new 类名(); // 这样就完成了对象的创建。
关于编译的过程
- 按说应该先编译Student.java,然后再编译StudentTest.java,但是对于编译器来说,编译StudentTest.java文件的时候,会自动找Student.class,如果没有,会自动编译Student.java文件,生成Student.class文件。
对象和引用的区别?
- 对象是通过new出来的,在堆内存中存储。
- 引用是:但凡是变量,并且该变量中保存了内存地址指向了堆内存当中的对象的。
构造方法:
什么是构造方法,有什么用?
- 构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建,以及实例变量的初始化。换句话说:构造方法是用来创建对象,并且同时给对象的属性赋值。(注意:实例变量没有手动赋值的时候,系统会赋默认值。)
重点(需要记忆):
- 当一个类没有提供任何构造方法,系统会默认提供一个无参数的构造方法。(而这个构造方法被称为缺省构造器。)
- 当一个类中手动的提供了构造方法,那么系统将不再默认提供无参数构造方法。建议将无参数构造方法手动的写出来,这样一定不会出问题。
调用构造方法怎么调用呢?使用哪个运算符呢?
- 使用new运算符来调用构造方法。
- 语法格式:new 构造方法名(实际参数列表);
构造方法的语法结构
- [修饰符列表] 构造方法名(形式参数列表){
构造方法体; 通常在构造方法体当中给属性赋值,完成属性的初始化。 }
- 注意:
- 第一:修饰符列表千万不要写static。
- 第二:构造方法名和类名必须一致。
- 第三:构造方法不需要指定返回值类型,也不能写void,写上void表示普通方法,就不是构造方法了。
- 普通方法的语法结构是:
[修饰符列表] 返回值类型 方法名(形式参数列表){ 方法体; }
无参数构造方法和有参数的构造方法都可以调用。
- 例如:
- Student x = new Student();
- Student y = new Student(123);
构造方法支持方法重载吗?
- 构造方法是支持方法重载的。在一个类当中构造方法可以有多个,并且所有的构造方法名字都是一样的。
- 方法重载特点:在同一个类中,方法名相同,参数列表不同。
实例变量的默认值
- 对于实例变量来说,只要你在构造方法中没有手动给它赋值,统一都会默认赋值。默认赋系统值。
- 那么这个默认赋值操作是在什么时间进行的?是在类加载的时候给这些实例变量赋值吗?
- 不是,实例变量是在构造方法执行的过程中完成初始化的,完成赋值的。
带有static的方法,没有static的方法,分别怎么调用?
- 带有static的方法怎么调用?通过“类名.”的方式访问。
- 对象被称为实例。实例相关的有:实例变量、实例方法。
- 实例变量是对象变量。实例方法是对象方法。实例相关的都需要先new对象,通过“引用.”的方式去访问。
封装有什么用?
- 一个类体当中的数据,假设封装之后,对于代码的调用人员来说,不需要关心代码的复杂实现,只需要通过一个简单的入口就可以访问了。另外,类体中安全级别较高的数据封装起来,外部人员不能随意访问,来保证数据的安全性。
- 封装的作用有两个:
- 第一个作用:保证内部结构的安全。
- 第二个作用:屏蔽复杂,暴露简单。
怎么进行封装,代码怎么实现?
- 第一步:属性私有化(使用private关键字进行修饰。)
- private(私有的)是可以在本类中访问的,在其它类中必须使用set和get方法访问。
- 第二步:对外提供简单的操作入口。
- 写一个方法专门来完成读。(get)
- 写一个方法专门来完成写。(set)
- get和set方法应该带有static,还是不应该有static?get和set方法应该定义为实例方法吗?
- get读年龄,set改年龄,这个读和改都是操作的一个对象的年龄。(没有对象何来年龄)
- 封装的第二步:对外提供公开的set方法和get方法作为操作入口。并且都不带static。都是实例方法。
- [修饰符列表] 返回值类型 方法名(形式参数列表){}
- 注意:java开发规范中有要求,set方法和get方法要满足以下格式。
- get方法的要求:
public 返回值类型 get+属性名首字母大写(无参){ return xxx; } - set方法的要求:
public void set+属性名首字母大写(有1个参数){ xxx = 参数; }
相关代码
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int nianLing){
if(nianLing < 0 || nianLing > 150){
System.out.println("对不起,年龄值不合法,请重新赋值!");
return;
}
age = nianLing;
}
}
public class PersonTest{
public static void main(String[] args){
Person p1 = new Person();
System.out.println(p1.age);
p1.age = 50;
System.out.println(p1.age);
p1.age = -100;
System.out.println("您的年龄值是:" + p1.age);
}
}
|