文章目录
传送门:
05 Java面向对象编程
1. 面向过程与面向对象比较
2. 类和对象
世界由对象组成;类可以生成对象,类是对象的抽象。类是对象的抽象,对象是类的实例化。先有具体的对象,然后抽象各个对象之间象的部分,归纳出类通过类再认识其他对象。
2.1 对象的属性和方法
对象是用来描述客观事物的一个实体,由一组属性和方法构成。
- 对象的属性:对象具有的各种特征
每个对象的每个属性都拥有特定值 - 对象的方法:对象执行的操作
Java中只有方法概念没有函数概念!
2.2 类的属性和方法
-
类的属性(成员变量)
属性用于定义该类或该类对象包含的数据或者说静态属性。属性作用范围是整个类体。在定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化。
属性定义格式:[修饰符] 属性类型 属性名 = [默认值]
- 修饰符可以省略,可以是:public, protected, private,Static,final
- 属性类型可以是任何类型,包括基本类型和引用类型
- 属性名:合法标识符即可。首字母小写,驼峰原则
-
类的方法
面向对象中,整个程序的基本单位是类,方法是从属于对象的。方法定义格式:[修饰符] 方法返回值类型 方法名(形参列表){ //n条语句 }
JAVA中方法参数传递是值传递!
2.3 定义一个类
定义一个类的步骤:
- 定义类名
- 编写类的属性
- 编写类的方法
/*
* 所有类定义的时候可以添加属性和方法,但是不是必须要写的。
* 一个java文件中可以定义N个class,但是只能有一个public class
* 属性:[修饰符] 属性类型 属性名 = [默认值]
* 方法:[修饰符] 方法返回值类型 方法名(形参列表){
//n条语句
}
* 注意:
* 1.方法的访问修饰符可以不写
* 2.方法可以有返回值,也可以没有,void表示没有返回值的意思
* 3.形参列表可以有,也可以没有
*/
public class Student {
//定义类属性
int stuNumber;
String name;
int age = 20;
//定义类方法
void study(){
System.out.println("我正在学习");
}
void eat(String food){
System.out.println("我正在吃"+food);
}
}
2.4 创建和使用对象
- 创建对象:使用new关键字来创建
类名 对象名 = new 类名();
- 使用对象成员:使用“.”进行以下操作
- 引用类的属性:对象名.属性
- 引用类的方法:对象名.方法名()
public class Student {
//定义类属性
int stuNumber;
String name;
int age = 20;
//定义类方法
void study(){
System.out.println("我正在学习");
}
void eat(String food){
System.out.println("我正在吃"+food);
}
public static void main(String[] args) {
//创建对象
Student student = new Student();
//使用属性
System.out.println(student.name);
System.out.println(student.age);
System.out.println(student.stuNumber);
//使用方法
student.study();
student.eat("苹果");
}
}
null
20
0
我正在学习
我正在吃苹果
2.5 对象和类的总结
- 对象和类的关系:特殊到一般,具体到抽象。
- 类:我们叫做class。对象:我们叫做Object instance(实例)。以后我们说某个类的对象,某个类的实例。是一样的意思。
- 类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
- 类是用于描述同一类形的对象的一个抽象的概念,类中定义了这一类对象所应具有的静态和动态属性。
- 对象是Java程序的核心,在Java程序中“万事万物皆对象"。
- JDK提供了很多类供编程人员使用,编程人员也可定义自己的类。
2.6 类和对象的课后作业
-
定义管理员类
实现思路:
- 定义管理员类Administrator
- 定义其属性和方法
- 定义测试类TestAdministrator
- 创建两个管理员类的对象,并输出他们的信息
/* * 创建管理员对象 * */ import java.util.Scanner; public class Administrator { String loginName = "admin";//用户名 String password = "123456";//密码 public void introduce() { System.out.println(loginName); System.out.println(password); } public static void main(String[] args) { //创建对象 Administrator admin = new Administrator(); admin.introduce(); } }
-
更改管理员密码
需求说明:
- 输入旧的用户名和密码,如果正确,方有权限更新
- 从键盘获取新的密码,进行更新
实现思路:
- 创建管理员类的对象
- 利用while实现循环执行
/* * 创建管理员对象 * */ import java.util.Scanner; public class Administrator { String loginName = "admin";//用户名 String password = "123456";//密码 public void introduce() { System.out.println(loginName); System.out.println(password); } //输入旧的用户名和密码,如果正确,方有权限更新 //从键盘获取新的密码,进行更新 public static void main(String[] args) { //创建对象 Administrator admin = new Administrator(); //从控制台读取数据 Scanner sc = new Scanner(System.in); System.out.println("修改密码"); while (true){ System.out.println("请输入用户名称:"); String name = sc.nextLine(); System.out.println("请输入密码:"); String pwd = sc.nextLine(); //如果密码正确,才有权限更新新密码 //字符串在比较的时候使用equal,不使用==;==比较的是内存地址 if (name.equals(admin.loginName) && pwd.equals(admin.password)){ admin.loginName = sc.nextLine(); admin.password = sc.nextLine(); break; } else{ System.out.println("用户名和密码不正确,请重新输入!"); } } } }
3. 局部变量和成员变量
区别:
- 声明位置不同
成员变量在类中,局部变量在方法中 - 作用范围不同
成员变量作用在当前类方法中,局部变量作用在当前方法中(不同方法中即使有同名的局部变量,没有关系,互不影响,建议相同) - 内存存放位置不同
局部变量存放在栈内存中,成员变量存放在堆内存中 - 成员变量有默认值;局部变量没有默认值
/*
* 变量:
* 局部变量:定义在方法中的变量,称为局部变量
* - 作用域:从定义位置开始到整个方法结束
* - 局部变量只能在当前方法中使用,其他方法无法使用
* - 局部变量不包含默认值,如果没有使用当前变量的话,可以不赋值
* 成员变量:定义在类中的变量称为成员变量(全局变量)
* - 作用域:当前类方法中
* - 成员变量包含初始值 int 0 String null bollean false
* */
public class VarDemo {
// 成员变量
static int age = 20;
public void test(){
System.out.println("2-----------"+age);
age = 10; //成员变量重新赋值
System.out.println("3-----------"+age);
//局部变量
int age = 30;
System.out.println("4-----------"+age);
}
public void show(){
//局部变量
int a = 10;
String name = "liujie";
}
public static void main(String[] args) {
System.out.println("1-----------"+age);
// System.out.println(a); //局部变量的作用域只在当前方法中
new VarDemo().test();
System.out.println("5-----------"+age); //这里打印出来是10
}
}
1-----------20
2-----------20
3-----------10
4-----------30
5-----------10
4.引用类型
Java语言中除基本类型之外的变量类型都称之为引用类型。
Java中的对象和数组是通过引用对其操作的。
- 引用可以理解为一种受限的指针
- 指针是可以进行与整数做加减运算的,两个指针之间也可以进行大小比较运算和相减运算。引用不行,只能进行赋值运算。
- 引用就是一个变量或对象的别名(引用的本质是一个对象);指针是一个段内存空间的地址(指向存储一个变量值的空间或一个对象的空间)。
引用只能保存对应的地址,通过地址找到内存空间里的值。
5. 内存分析
-
栈(FILO)
- 存放:局部变量
- 后进先出,自下而上存储
- 方法执行完毕,自动释放空间
-
堆
- 存放:new出来的对象
- 需要垃圾回收器来回收:
System.gc()
-
方法区
- 存放:类的信息(代码)、static变量、字符串常量等
public class Student {
//定义类属性
int stuNumber;
String name;
int age = 20;
//定义类方法
void study(){
System.out.println("我正在学习");
}
void eat(String food){
System.out.println("我正在吃"+food);
}
public static void main(String[] args) {
//创建对象
Student student = new Student();
//使用属性
System.out.println(student.name);
System.out.println(student.age);
System.out.println(student.stuNumber);
//修改属性值,给属性赋值
student.name = "张三";
student.age = 40;
student.stuNumber = 2019210004;
//使用属性
System.out.println(student.name);
System.out.println(student.age);
System.out.println(student.stuNumber);
//使用方法
student.study();
student.eat("苹果");
}
}
6. 构造方法
构造方法:创建对象的时候默认会调用构造方法来创建对象,在堆中开辟空间,完成成员变量的某些初始化。
构造方法的语法(特点):
- 方法名称:构造方法的方法名称必须跟类名称保持一致
- 访问修饰符:
- 形参:可以用户自定义添加,跟方法的普通参数一样
- 方法体:完成对象的初始化功能
- 返回值:没有返回值
注意:
- 创建完类之后,如果没有手动调用构造方法,会有一个默认的无参的构造方法供调用
- 当用户自定义了构造方法之后,默认的无参构造方法就不能使用了, 必须手动定义无参构造方法
- 同一个类中可以包含多个同名的构造方法
public class Teacher {
String name;
int age;
//构造方法1
public Teacher(){
}
//构造方法2
public Teacher(String xname,int xage){
System.out.println("two argumnet");
name = xname;
age = xage;
}
public void teach(){
System.out.println("上课");
}
public static void main(String[] args) {
//构造方法1
Teacher teacher = new Teacher();
teacher.name = "liujie";
teacher.age = 25;
System.out.println(teacher.name);
System.out.println(teacher.age);
//构造方法2
Teacher teacher2 = new Teacher("lisi",20);
System.out.println(teacher2.name);
System.out.println(teacher2.age);
Teacher teacher3 = new Teacher("wangwu");
System.out.println(teacher3.name);
}
}
liujie
18
two argumnet
lisi
20
one argumnet
wangwu
6.1 重载
在一个类中可以包含多个重名的方法,但是注意方法的参数列表不能相同。
三个方面的不同:
- 参数的个数不同
- 参数的类型不同
- 参数的顺序不同
注意:当自定义构造方法后,系统不再默认提供无参构造方法。一般构造方法都会进行重载(一个类中可以包含多个属性值,当只需要给部分属性初始化时需要调用不同的构造方法)。
public class Teacher {
String name;
int age;
//构造方法1
public Teacher(){
}
//构造方法2
public Teacher(String xname,int xage){
System.out.println("two argumnet");
name = xname;
age = xage;
}
//构造方法重载
public Teacher(String xname){
System.out.println("one argumnet");
name = xname;
}
public void teach(){
System.out.println("上课");
}
public static void main(String[] args) {
//构造方法1
Teacher teacher = new Teacher();
teacher.name = "liujie";
teacher.age = 18;
System.out.println(teacher.name);
System.out.println(teacher.age);
//构造方法2
Teacher teacher2 = new Teacher("lisi",20);
System.out.println(teacher2.name);
System.out.println(teacher2.age);
Teacher teacher3 = new Teacher("wangwu");
System.out.println(teacher3.name);
}
}
liujie
18
two argumnet
lisi
20
one argumnet
wangwu
7. 构造器
构造器定义:constructor构造方法,一个在创建对象时被自动调用的特殊方法。
- 构造器的作用:为对象进行初始化(成员变量)工作
- 构造器是一种特殊的方法:
- 构造器的方法名必须和类名一致!
- 构造器虽然有返回值,但是不能定义返回类型(返回值的类型肯定是本类),不能在构造器里调用return。
- 通过new关键字调用!
- 如果我们没有定义构造器,则系统会自动定义一个无参的构造方法。如果已定义则编译器不会添加无参构造方法
- 与普通方法一样,构造方法也可以重载
案例:
定义一个“点”(Point)类用来表示二维空间中的点(有二个坐标)。要求如下:
- 可以生成具有特定坐标的点对象。
- 提供可以设置二个坐标的方法。
- 提供可以计算该"点"距另外点距离的方法。
- 代码实现交换point中两个坐标的值(实现用对象作为参数)
public class Point {
int x;
int y;
//设置二维坐标点
public void set(int xx, int yy) {
x = xx;
y = yy;
}
// 计算该“点“距另外点的距离
public double caclcDistance(Point p) {
return Math.sqrt((p.x - x) * (p.x - x) + (p.y - y) * (p.y - y));
}
//交换point中两个坐标的值(实现用对象作为参数)
public void changePoint(Point p){
int a = p.x;
p.x = x;
x = a;
int b = p.y;
p.y = y;
y = b;
}
//打印坐标点
public void show(){
System.out.println("["+x+","+y+"]");
}
//主函数
public static void main(String[] args) {
//设置第一个点
Point p1 = new Point();
p1.set(3,5);
//设置第二个点
Point p2 = new Point();
p2.set(2,4);
//计算两点之间的距离
System.out.print("计算两点之间的距离:");
System.out.println(p1.caclcDistance(p2));
//交换第一个点与第二个点的值,并打印
p1.changePoint(p2);
p1.show();
p2.show();
}
}
计算两点之间的距离:1.4142135623730951
[2,4]
[3,5]
8. 方法调用
- 形参和实参
- 定义方法的参数是形式参数
- 调用方法的参数是实在参数
- 调用方法时要求参数个数相同,类型兼容
- 参数传递
- 基本数据类型的参数传递:无法通过方法调用改变变量的值
- 引用数据类型的参数传递:可以通过方法调用改变变量的值
基本数据类型的参数传递:无法通过方法调用改变变量的值
package com.mashibing;
/*
* 方法参数的值是否改变
* 方法中的参数列表叫做形式列表,没有具体的值,只是为了方便在方法体中使用
* 调用方法的时候实际传入的值叫做实参,代表具体的数值,用来替换在方法体中代码逻辑的值进行运算
* 注意:
* 1.形式参数的变量名称也是局部变量
* 2.基本数据类型的参数传递:不能改变参数的值
* */
public class ArgumentDemo {
public static void test(int a,int b){
int tmp = a;
a = b;
b = tmp;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
test(a,b);
System.out.println(a);
System.out.println(b);
}
}
10
20
引用数据类型的参数传递:可以通过方法调用改变变量的值
Point.java
package com.mashibing;
public class Point {
private int x;
private int y;
public Point(int x,int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
ArgumentDemo.java
package com.mashibing;
/*
* 方法参数的值是否改变
* 方法中的参数列表叫做形式列表,没有具体的值,只是为了方便在方法体中使用
* 调用方法的时候实际传入的值叫做实参,代表具体的数值,用来替换在方法体中代码逻辑的值进行运算
* 注意:
* 1.形式参数的变量名称也是局部变量
* 2.基本数据类型的参数传递:不能改变参数的值
* java中的参数传递是值传递
* */
public class ArgumentDemo {
public static void test(Point point){
int x = point.getX();
int y = point.getY();
int tmp = x;
x = y;
y = tmp;
point.setX(x);
point.setY(y);
}
public static void main(String[] args) {
Point point = new Point(2,3);
test(point);
System.out.println(point.getX());
System.out.println(point.getY());
}
}
3
2
9. This关键字
this表示的是当前对象本身,this代表当前对象的一个引用。
- 普通方法中使用this
- 区分成员属性和方法的形参
- 调用当前对象的其他方法(可以省略)
- 位置:任意
- 构造方法中使用this
- 当构造方法中的参数名称跟类的成员变量一样的时候,可以使用this代表当前对象。有了this后可以将构造方法的参数跟成员变量的保持一致
- 当构造方法中需要调用其他的构造方法时,可以使用this()(这个括号相当this.ThisDemo())调用其他构造方法,但是必须位于构造方法第一行
this不能用于static方法。
/*
* this关键字:表示当前对象的指针
* 用处:
* 1.构造方法:当构造方法中的参数名称跟类的成员变量一样的时候,可以使用this代表当前对象
* 有了this后可以将构造方法的参数跟成员变量的保持一致
* 当构造方法中需要调用其他的构造方法时,可以使用this()(这个括号相当于this.ThisDemo())调用其他构造方法,
* 但是必须位于构造方法第一行
* 2.普通方法:当多个普通方法之间需要调用时,可以使用this进行调用,指的是当前对象的其他方法
* 3.成员变量的使用:当方法中的参数名称跟成员变量保持一致的时候,使用this表示的是对象的值
* 使用变量名称表示的是形参的值
* 4.只要在当前类中定义的this都表示同一个this
* */