第七章—类与对象
1.面向对象和面向过程概念
所谓面向对象和面向过程其实就是解决问题时不同的两种思考方式。
面向对象:顾名思义就是解决问题时直接以结果为目标,不考虑其中的过程。
面向过程:与面向对象相反,面向过程是侧重与执行解决问题的过程。
举个例子就是:面向过程可以理解为肚子饿了自己买菜、洗菜、自己做饭吃,而面向对象就是直接从根源解决问题,直接点外卖或者喊妈妈做,不需要自己动手操作过程,只需要给出结果即可。
面向过程是最底层的,面向对象是基于面向过程的!
2.类和对象的关系
对象:任何东西都可以说是一个对象
类:具有相同属性和功能的对象的统称
当我们在定义一个类的时候,也主要从属性和行为这两个方面来说
属性:可以量化的,用数据来表示,都是一些变 量——成员变量
行为:行为是一些列的动作,这些系列的动作可以用函数来封装表示——成员函数
总的来说,类是对象的抽象,而对象是类的具体实例。
3.代码实现
当要创建一个类的时候,首先要考虑好这个类所需要的属性和行为,比如要创建一个人的类,就要在类中描述清楚这个人的年龄,身高,外貌等属性和这个人要做什么行为,要创建一个汽车类则需要描述汽车的品牌,颜色等属性,和加速,刹车等行为。
代码示例:
public class Car{
String band;
String color;
int speed;
int weight;
boolean statues;
public void startEngine() {
if (statues) {
System.out.println("汽车引擎关闭....");
statues = false;
} else {
System.out.println("汽车引擎启动....");
statues = true;
}
}
public void shutDownEngine() {
if (statues) {
System.out.println("汽车引擎关闭....");
statues = false;
} else {
System.out.println("汽车引擎启动....");
statues = true;
}
}
public void addSpeed() {
if (statues) {
System.out.println("汽车加速....");
speed += 10;
} else {
System.out.println("汽车引擎尚未启动....");
}
}
public void jianSpeed() {
if (statues) {
System.out.println("汽车减速....");
speed -= 10;
if (speed <= 0) {
speed = 0;
}
} else {
System.out.println("汽车引擎尚未启动....");
}
}
}
当需要调用这个类的时候,只需要 new一个对象——new Car() ,这就实现了在堆内存中 开辟一个空间、给该空间分配一个随机的地址、然后在该空间中创建对应的成员变量,并对这些成员变量进行 默认初始化 。
创建出一个Car类的对象,对象的名字叫c1---- Car c1 = new Car();
c1是主函数中的局部变量;通过 c1.XXX 的形式,调用c1这个对象的成员变量,实现相关操作。
比如给一辆汽车品牌设定为奥迪,颜色为黑色,就可以使用
c1.band = "奥迪";
c1.color = "黑色";
4.局部变量与成员变量的区别
所属空间
成员变量:堆内存当中,对象的所属空间里
局部变量:栈内存当中,函数的所属空间里
生命周期
成员变量:随着对象的创建而创建,随着对象的消亡而消亡
局部变量:随着函数的进栈而创建,随着函数的弹栈而消失
初始化
成员变量:有默认初始化-显式初始化-针对性初始化
局部变量:如果没有初始化的值,那么后面不能调用
作用域
成员变量:在本类的内部是全局(静态不能调用非静态)
局部变量:前提是在函数中,在最近的一对大括号内
简单来说,成员变量是在类中创建,在堆内存中,而局部变量是在函数中,一个是类中的全局变量,一个是局部变量。
在代码中如何区分重名的成员变量和局部变量的调用?
通过this关键字进行区分,成员变量可以通过this.调用
5.private关键字与访问器修改器
private 是将成员变量变成私有化,外界无法访问也无法修改,但若是同一个类中的成员变量想修改默认值,则需要使用修改器(具有修改功能的函数)set***(),修改之前肯定要访问,所以同时需要访问器 get***()。
比如在下面这个类中,成员变量都是private私有的,想要修改和访问就需要声明修改器和访问器。
class RegularPolygon{
//定义成员变量
private int n = 3;
private double side = 1;
private double x = 0;
private double y = 0;
//构造函数
public RegularPolygon(){
}
public RegularPolygon(int n, double side){
this(n,side,0,0);
}
public RegularPolygon(int n, double side, double x, double y){
this.n = n;
this.side = side;
this.x = x;
this.y = y;
}
//成员函数
public double getPerimeter(){
return n * side;
}
public double getArea(){
return n * side * side / (4 * Math.tan(Math.PI / n));
}
//访问器修改器
public void setN(int n ){
this.n = n;
}
public void setSide(double side){
this.side = side;
}
}
6.构造函数
构造函数:就是在创建对象时调用的函数,一是给对象进行显示初始化+针对性初始化,二是为了继承相关的内容。
构造函数分为:
有参,无参
有返回值,无返回值
构造函数特点:
1)函数名必须和类名是一致的
2)无返回值,没有返回值类型,但是有return存在
3)权限随意,可以私有,也可以公共
4)也有参数列表
5)如果类中没有明显定义任何构造函数的话,那么会有一个隐藏的无参构造函数
6)如果明显定义了其他带参的构造函数的话,那么那个隐藏的无参构造函数就消失啦! 所以,一般建议都把无参的写出来
7)构造函数之间是有重载关系的(重载的前提是同一个类中函数重名,但参数的数据类型排列组合不一样)
8)构造函数可以调用构造函数,通过this(XXX)方式;但是不能相互调用,并且this(xxx)必须在第一行
7.static静态成员
静态变量:
同一个类中,所有对象都具有相同的属性和值的话,那么在创建对象时,这部分相同的内容也会被重复好多次,占据内存空间,则将重复的属性值提取出来,变成所有对象之间共享的数据即可,就是静态变量。
静态函数:
没有重复和提取的事,什么时候定义静态函数,就看该函数中是否访问非静态,如果不访问则可以定义成静态函数,如果需要访问成员变量或其他成员函数的话,就不能定义为静态函数。 如果静态函数中需要访问某个对象的成员变量和成员函数时,就必须得先创建该对象,在通过对象去调用即可
在同一个类中,静态优先于对象存在,后于对象消失
直接调用变量的寻找顺序:
成员函数中:局部变量-成员变量-静态变量
静态函数中:局部变量-静态变量
静态变量和成员变量的区别
存储位置
成员变量:存在于堆内存中,对象的所属空间里
静态变量:存在于静态方法区中,某一个类(字节码)的空间里
生命周期
成员变量:随着对象的创建而创建,随着对象的消亡而消亡
静态变量:随着类的加载而创建,随着类的卸载(程序结束)而消亡
调用方式
成员变量:要么创建对象之后,通过对象来调用(没有private的话);要么在类中,由别的成员函
数来调用
静态变量:要么在外界通过类名直接调用(没有private的话);要么在类中,由别的成员函数或静
态函数来调用