要理解面向对象思想,我们先要知道什么是对象?
《Java编程思想》中提到“万物皆为对象”的概念。它将对象视为一种奇特的变量,它除了可以存储数据之外还可以对它自身进行操作。它能够直接反映现实生活中的事物,例如人、车、小鸟等,将其表示为程序中的对象。每个对象都具有各自的状态特征(也可以称为属性)及行为特征(方法),java就是通过对象之间行为的交互来解决问题的。
面向对象就是把构成问题的事物分解成一个个对象,建立对象不是为了实现一个步骤,而是为了描述某个事物在解决问题中的行为。
类是面向对象中的一个很重要的概念,因为类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。
类具有三个特性:封装、继承和多态。
三大特征
1、封装:核心思想就是“隐藏细节”、“数据安全”,将对象不需要让外界访问的成员变量和方法私有化,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,保证了数据的安全和程序的稳定。所有的内容对外部不可见。
2、继承:子类可以继承父类的属性和方法,并对其进行拓展。将其他的功能继承下来继续发展 。
3、多态:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以及方法的重写和重载可以实现多态。方法的重载本身就是一个多态性的体现。
类与对象
类表示一个共性的产物,是一个综合的特征,而对象,是一个个性的产物,是一个个体的特征。 (类似生活中的图纸与实物的概念。)
类必须通过对象才可以使用,对象的所有操作都在类中定义。
类由属性和方法组成:
-
属性:就相当于人的一个个的特征
-
方法:就相当于人的一个个的行为,例如:说话、吃饭、唱歌、睡觉
一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
类名称 对象名称 = new 类名称() ;
如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:
访问类中的属性: 对象.属性 ;
调用类中的方法: 对象.方法(实际参数列表) ;
1、类必须编写在.java文件中;
2、一个.java文件中,可以存在N个类,但是只能存在一个public修饰的类;
3、.java文件的文件名必须与public修饰的类名完全一直;
4、同一个包中不能有重名的类;
匿名对象
- 没有对象名称的对象就是匿名对象。 即栈内存中没有名字,而堆内存中有对象。
- 匿名对象只能使用一次,因为没有任何的对象引用,所以将称为垃圾,等待被GC回收。
- 只使用一次的对象可以通过匿名对象的方式完成,这一点在以后的开发中将经常使用到。
public static void main(String[] args){
//Math2 m=new Math2();
//int num=m.sum(100,200);
//不通过创建对象名,直接实例对象调用,这就是匿名对象。
//因为没有对象名指向对象,所以只能调用一次,然后被GC回收。
int num = new Math().sum(100,200);
System.out.println(num);
}
class Math2{
int sum(int x,int y){
return x+y;
}
}
类与对象之间关系
定义一个类的对象,其实就是创建一个类的实例,表示一个具体的对象。
格式: 类名 对象名 = new 类名();
例如: 人类 亚当 = new 人类();
左边的这个人类,表示亚当的类型是人类,右边的 new 人类(); 表示亚当是一个具体的实例,拥有人类的行为和特征。
在声明一个具体对象时,如果只声明对象而没有给出具体实例,例如
People p1 =null; 或者 People p2 ;
此时p1 和p2 无法正常使用,因为没有具体的内存指向。
p1 = new People(); p2 = new People();
在有了具体的内存指向后,p1和p2 才可以正常使用
对 象
(1)概念
生活中:真实存在的事物就是对象
代码中:使用代码模拟生活中存在的对象
/*万事万物皆对象*/
(2)如何创建一个对象
语法:
数据类型(类名) 对象名 = new 类名(实参列表);
本质:
调用类中的构造函数,
要求:
调用构造函数时,传入的实参列表要与构造函数定义时的形参列表,长度一致,顺序一致,数据类型一致
(3)对象的创建过程
语法:
类名 对象名 = new 类名(实参列表);创建过程:
1,在堆内存开辟一片运行内存
2,给对象的属性赋初始值(基本数据类型默认为0(值存储在堆中),引用数据类型默认为null(存储的是引用数值所在的地址))
3,执行构造函数中的代码
4,将栈中的引用指向堆中开辟的内存地址
类
(1)概念
多个对象抽取其共同点形成的概念,就称为类
(2)如何创建一个类
语法:
访问权限修饰符 class 类名{
}
类名:符合大驼峰命名法,做到见名知意
定义的位置:
因为内部类还没有学习,所有将自定义类定义在 类 以外
(3)类中有什么
属性概念:用于描述对象的静态特征
别名:成员变量
本质:就是在方法外,类中定义的变量
定义的格式:
访问权限修饰符 数据类型 变量名;
注意:只能使用该类对象调用
构造函数概念:用于创建该类对象,因为构造函数的方法名必须与类名一致,所以new调用的就是构造函数
别名:构造方法
本质:一个特殊的方法
定义的格式:
访问权限修饰符 类名(形参列表){
方法体
}
定义位置:
类中,方法以外
注意:1.只能使用new关键字调用
2.如果一个类中没有构造函数,系统会为其提供一个无参的构造函数
方法概念:用于描述对象的动态特征(行为)
别名:函数
本质:包装一段代码的容器
定义的格式:
访问权限修饰符 修饰符 返回值类型 方法名(形参列表){
方法体
return xxx;
}
返回值类型:如果方法有返回值,那么返回值类型就是返回值的数据类型,如果没有就写void
方法名:自定义,符合小驼峰命名法
定义位置:
类中,方法以外
属性的作用:描述对象 静态特征
构造函数的作用:创建该类对象
方法的作用:描述对象的 动态特征
(4)类与对象的关系
生活中:
先有对象后有类
代码中:
现有类后有对象
(5)局部变量与成员变量
1.在类中的位置不同
成员变量:在类中定义
局部变量:在方法中定义或方法的参数2.在内存中的位置不同
成员变量:在堆内存(成员变量属于对象,对象进堆内存)
局部变量:在栈内存(局部变量属于方法,方法进栈内存)3.声明周期不同
成员变量:随着对象的创建而存在,随着对象的销毁而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失4.初始化值不同
成员变量:有默认初始化值,引用数据类型默认为null
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用
5.权限修饰符不同
局部变量:无权限修饰符
成员变量:存在权限修饰符注意:局部变量名称可以和成员变量名称一样,在方法中使用时,采用就近原则(若其为对象可以采用this区分)
(6)静态变量与成员变量的区别
静态变量:
1. 调用方式:类名.属性名或对象名.属性名
2.属于 该类 所有的对象
成员变量:
1.调用方式:对象名.属性名
2.属于 具体 的某一对象
(7)构造函数与方法的区别
1、格式区别
构造方法和类名相同,并且没有返回类型,也没有返回值;不可被重写、不可被继承(可以被调用);可用this、super调用本类和父类的构造函数。
普通成员方法可以任意起名,必须有返回类型,可以没有返回值;可被重写、可被继承;不可用this、super调用本类和父类的构造函数。
2、作用区别
构造方法用于创建对象,并进行初始化值。
普通成员方法是用于完成特定功能的。
3、调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
普通成员方法是由创建好的对象调用,可以调用多次
this的使用
(1)概念
哪一个对象调用this所在的方法,this就代指这个对象
(2)使用
1,当局部变量与成员变量重名时,用于区分成员变量与局部变量,this.属性名表示成员变量(属性)
2,在本类构造函数中,调用其他构造函数
this(实参列表);
注意:
1,必须在构造函数第一行
2,不要形成死循环
3,在本类中调用本类其他属性或方法,此时可以忽略this不写
面向对象(封装、继承、多态)
封装
(1)优点
思想:包装
优点:
1,美化
2,降低耦合度
3,保护内部
4,方便使用
(2)Java代码中的封装
变量:封装一个可以改变的数据
数组:封装一组数据
方法:封装一段代码
类:封装多个属性与多个方法
java文件:封装一个或多个类
包:封装多个java文件
项目:封装多个包
(3)包
本质:一个文件夹
创建包:
选择src文件夹,点击鼠标右键,选择new,选择package
填写包名
注意:
包名使用全小写,不要用数字开头,不要出现特殊符号
包名的命名潜规则:
com.公司名称缩写.作用
注意:.表示下一层文件夹
关键字:package导包:
关键字:import
为什么要导包:
所需使用的类与当前类不在同一个包中
(4)访问权限修饰符
意思:限制属性,方法,构造函数,类等的使用范围
分类:
关键字 意义 使用范围
public 公共的 当前项目中
protected 受保护的 当前包中或继承关系中
不写 默认的 当前包中
private 私有的 当前类中
总结:
一般情况下:
属性用private修饰,方法与类用public修饰
属性用private修饰后需提供get与set方法
继承
(1)优点
概念:
生活中的继承:晚辈获取长辈留下的财产与精神
代码中的继承:
多个类(B1,B2)抽取其共同点形成了一个类(A)
注意:
判断类A是否与类B有继承关系
如果类B与类A存在继承关系,可以让类B继承与类A,此时类B将拥有类A的所有属性与方法,构造函数除外
类B:称为子类
类A:称为父类
优点:
1,减少代码
2,使代码结构清晰
3,降低代码冗余度总结:
子类将拥有父类的所有属性与方法,构造函数除外(父类构造函数只能使用,不是拥有关系)
(2)继承的语法
语法:
访问权限修饰符 class 子类名 extends 父类名{
属性
构造函数
方法
}
注意:
1,Java只能单继承
2,如果一个类没有写继承,默认继承于Object
3,如果父类中的方法与子类方法名相同,形参列表相同,返回值类型相同,访问权限修饰符子类大于或等于父类该方法,这种方法称为重写
(3)super的使用
作用:子类中使用父类的内容
使用:
属性
特殊情况:子类的属性名与父类属性名相同,如何区分
子类:this.属性名
父类:super.属性名
方法
特殊情况:子类重写父类方法,在子类中使用该方法,如何区分是父类方法还是子类方法
子类:this.方法名(实参列表);
父类:super.方法名(实参列表);
构造函数
情况:创建子类对象时,需要给父类构造函数传值
语法:
super(实参列表);
注意:
1,要在子类构造函数第一行
2,子类构造函数中如果没有调用父类构造函数,那么默认在其第一行有super();调用父类无参构造函数
3,重写父类方法时,若访问权限修饰符比父类小,则会报错
总结:
子类将拥有父类的所有属性与方法,构造函数除外