目录
1.面向对象
1.1.对象是什么?
对象可以简单理解为一种特殊的数据结构,对象是用类new出来的,有了类就可以创建出对象。
基本结构为:
public class 类名{
1、变量,用来说明对象可以处理什么数据
2、方法,描述对象有什么功能,也就是可以对数据进行什么样的处理
.....
}
使用对象:
类名 对象名 = new 类名()
按照上面的我举一个例子,我首先创建一个Student的类:定义三个变量和两个方法
public class Student {
String name; //学生名字
double chinese; //语文成绩
double math; 数学成绩
//总成绩方法
public void printTotalScore(){
System.out.println(name+"的总成绩为:" +(chinese+math));
}
// 平均成绩方法
public void printAverageScore(){
System.out.println(name+"的总成绩为:" +(chinese+math)/2);
}
}
下面我们去创造两个对象:
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
s1.name = "小虎";
s1.chinese = 80.9;
s1.math = 90.1;
s1.printTotalScore();
s1.printAverageScore();
System.out.println("----------------------");
Student s2 = new Student();
s2.name = "小明";
s2.chinese = 100.5;
s2.math = 90.1;
s2.printTotalScore();
s2.printAverageScore();
}
}
打印结果:
看完以上相信大家对面向对象有一个初步的了解。
1.2.对象在计算机中执行原理
我们需要明白这三个东西,方法区,堆内存,栈内存,先看图
首先在方法区中,会存入要执行的所有方法,在mian 方法中我们通过new 创建了对个对象,此时会保存着栈内存中,每个对象(s1,s2)有他们对应的地址,在堆内存中会把传入或者写入的值赋值给所对应对象地址中的变量,最后在方法区执行。
1.3.类和对象的注意事项
(1)类名建议用英文单词,首字母大写,满足驼峰模式,且要有意义,比如:Student、Car…
(2)类中定义的变量也称为成员变量(对象的属性),类中定义的方法也称为成员方法(对象的行为)。
(3)成员变量本身存在默认值,同学们在定义成员变量时一般来说不需要赋初始值(没有意义)
(4)一个代码文件中,可以写多个class类,但只能一个用public修饰,且public修饰的类名必须成为代码文件名。
我新增两个class 不会报错
package com.hu.struct;
public class Student {
String name;
double chinese;
double math;
public void printTotalScore(){
System.out.println(name+"的总成绩为:" +(chinese+math));
}
public void printAverageScore(){
System.out.println(name+"的总成绩为:" +(chinese+math)/2);
}
}
class Peoson{
}
class Animal{
}
这样写就会报错了,写了多个public
下面这种写法也会,public 修饰的不是与文件名相同的类
(5)对象与对象之间的数据不会相互影响,但多个变量指向同一个对象时就会相互影响了。
如果某个对象没有一个变量引用它,则该对象无法被操作了,该对象会成为所谓的垃圾对象。
package com.hu.struct;
public class Test {
public static void main(String[] args) {
Student s2 = new Student();
s2.name = "小明";
s2.chinese = 100.5;
s2.math = 90.1;
s2.printTotalScore();
s2.printAverageScore();
s2 = null;
System.out.println(s2.chinese);
}
}
这样对象我们无法操作了,而且会空指针报错
2.面向对象基础
2.1.方法
一个class
可以包含多个field,例如,我们给Person
类就定义了两个field:
class Person {
public String name;
public int age;
}
但是,直接把field
用public
暴露给外部可能会破坏封装性。比如,代码可以这样写:
Person ming = new Person();
ming.name = "Xiao Ming";
ming.age = -99; // age设置为负数
显然,直接操作field
,容易造成逻辑混乱。为了避免外部代码直接去访问field
,我们可以用private
修饰field
,拒绝外部访问:
class Person {
private String name;
private int age;
}
试试private
修饰的field
有什么效果:
// private field
public class Main {
public static void main(String[] args) {
Person ming = new Person();
ming.name = "Xiao Ming"; // 对字段name赋值
ming.age = 12; // 对字段age赋值
}
}
class Person {
private String name;
private int age;
}
是不是编译报错?把访问field
的赋值语句去了就可以正常编译了。 把field
从public
改成private
,外部代码不能访问这些field
,那我们定义这些field
有什么用?怎么才能给它赋值?怎么才能读取它的值?
所以我们需要使用方法(method
)来让外部代码可以间接修改field
:
// private field
public class Main {
public static void main(String[] args) {
Person ming = new Person();
ming.setName("Xiao Ming"); // 设置name
ming.setAge(12); // 设置age
System.out.println(ming.getName() + ", " + ming.getAge());
}
}
class Person {
private String name;
private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
if (age < 0 || age > 100) {
throw new IllegalArgumentException("invalid age value");
}
this.age = age;
}
}
虽然外部代码不能直接修改private
字段,但是,外部代码可以调用方法setName()
和setAge()
来间接修改private
字段。在方法内部,我们就有机会检查参数对不对。比如,setAge()
就会检查传入的参数,参数超出了范围,直接报错。这样,外部代码就没有任何机会把age
设置成不合理的值。对setName()
方法同样可以做检查,例如,不允许传入null
和空字符串:
public void setName(String name) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("invalid name");
}
this.name = name.strip(); // 去掉首尾空格
}
同样,外部代码不能直接读取private
字段,但可以通过getName()
和getAge()
间接获取private
字段的值。所以,一个类通过定义方法,就可以给外部代码暴露一些操作的接口,同时,内部自己保证逻辑一致性。调用方法的语法是实例变量.方法名(参数);
。一个方法调用就是一个语句,所以不要忘了在末尾加;
。例如:ming.setName("Xiao Ming");
。