-
类:对现实世界中事物的抽象。Student
-
对象:现实世界中具体的个体。张三、李四 这些具体的学生
-
面向对象的特征:抽象、封装、继承、多态
- OOP: Object Oriented Programming
-
类和对象的总结:
- 现实世界都是由很多对象组成的,基于对象的共同特征抽象出类。
- 对象:真实存在的对象
- 类中包含:
- 所有对象所共有的特征– 属性(静)
-
所有对象所共有的行为--方法(动)
-
类是对象的模板,对象是类的具体实例。
-
一个类可以创建多个对象:同一个类的不同对象,结构相同,数据不同。
易混淆知识点:
int num = 3;
int[] nums = new int[3];
Student student = new Student(); // student :变量、实例、对象
Student[] students = new Student[3];
Teacher teacher = new Teacher();
Teacher[] teachers = new Teacher[3];
int、int[]、Student、Student[]这些都是数据类型,数据类型的后面是这种类型的一个变量。
格式: 数据类型 变量
var v;
数据类型的默认值:
int类型默认值是:0
double类型默认值是:0.0
boolean类型默认值是:false
String类型默认值是:null
int[]类型默认值是:null
Student[]类型默认值是:null
boolean[]类型默认值是:null
int[] array = new int[3]; 里面的存放默认值是0
boolean[] array = new boolean[3]; 里面的存放默认值是false
Student[] array = new Student[3];里面的存放默认值是null
ArrayIndexOutOfBoudsException 数组下标越界异常
NullPointerException空指针异常(引用数据类型)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cNoqgPes-1657806947304)(面向对象.assets/1657721297633.png)]
面向对象:抽象、封装、继承、多态
- 属性私有,通过get、set方法访问:
- 构造方法:
特点:1、方法名和类名一样 2、没有返回值
//无参构造方法
//如果不写,Java默认提供这样一个无参构造方法.
//如果你写了,Java就不会再提供这个无参构造方法
public Student() {
System.out.println("Student.Student()");
}
- this:
Student student = new Student(1, "zhansgan", 20);
//有参构造方法
public Student(int id, String name, int age) {
this.id = id;//把1这个值赋值给当前new出来的student对象的id属性
this.name = name;
this.age = age;
}
this代表当前对象,把通过构造方法传递过来的值赋值给当前对象的id。
如果不写任何构造方法,系统默认提供一个无参数构造方法,只是我们看不到而已。
如果自己写了任何一个构造方法,系统就不会提供这个默认无参构造方法。所以说如果自己写了一个带参数的构造方法,就要把无参数构造方法也要写上。
(后面使用或者学习的一些框架要new这个无参数的构造方法)
(只要你写了任何一个构造方法,不管有参没参,系统都不会给你提供默认无参构造方法)
- 构造方法和一般方法的不同:
- 构造方法是在new对象的时候运行,而一般的方法是在对象调用的时候才执行。
- 一个对象的建立,构造方法只执行一次,而一般方法可以被改对象调用多次。
- 练习:
- 编写Java程序,模拟简单的计算器。
定义名为Number的类,其中有两个整型数据成员num1和num2,应声明为私有。编写构造方法,赋予num1和num2初始值,再为该类定义加(add)、减(sub)、乘(multi)、除(div)等公有成员方法,分别对两个成员变量执行加、减、乘、除的运算。 在main方法中创建Number类的对象,调用各个方法,并显示计算结果。
Number类:
public class Number {
private int num1;
private int num2;
public Number() {
}
public Number(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}
public int add() {
return num1 + num2;
}
public int sub() {
if (num1 >= num2) {
return num1 - num2;
} else {
return num2 - num1;
}
}
public int multi() {
return num1 * num2;
}
public double div() {
if (num2 == 0) {
return 0;
}
return num1 * 1.0 / num2;
}
主函数类:
public class Day4 {
public static void main(String[] args) {
Number number = new Number(10, 20);
System.out.println("两个数相加的和为:" + number.add());
System.out.println("两个数相减的差为:" + number.sub());
System.out.println("两个数相乘的奇为:" + number.multi());
System.out.println("两个数相除的商为:" + number.div());
}
结果:
- 定义长方形类,含:
属性:宽、高(整型);
方法:求周长、面积;
构造方法3个:(1)无参——宽、高默认值为1;(2)1个参数——宽、高相等;(3)2个参数——宽、高各为参数值。
要求:进行测试计算周长和面积。
矩形类:
public class Rectangle {
private int width;
private int height;
public Rectangle() {
this.width = 1;
this.height = 1;
}
public Rectangle(int num) {
this.width = num;
this.height = num;
}
public Rectangle(int num1, int num2) {
this.width = num1;
this.height = num2;
}
public int perimeter() {
return (width + height) * 2;
}
public int area() {
return width * height;
}
主函数:
public class Day4 {
public static void main(String[] args) {
// Number number = new Number(10, 20);
// System.out.println("两个数相加的和为:" + number.add());
// System.out.println("两个数相减的差为:" + number.sub());
// System.out.println("两个数相乘的奇为:" + number.multi());
// System.out.println("两个数相除的商为:" + number.div());
Rectangle rectangle;
rectangle = new Rectangle();
System.out.println("矩形1的周长为:" + rectangle.perimeter());
System.out.println("矩形1的面积为:" + rectangle.area());
System.out.println("-------------------------");
rectangle = new Rectangle(4);
System.out.println("矩形2的周长为:" + rectangle.perimeter());
System.out.println("矩形2的面积为:" + rectangle.area());
System.out.println("-------------------------");
rectangle = new Rectangle(3, 5);
System.out.println("矩形3的周长为:" + rectangle.perimeter());
System.out.println("矩形3的面积为:" + rectangle.area());
}
结果:
2、封装、继承、多态、抽象
-
继承: 你继承谁你就是谁,继承是一种严格的父子关系(在父类里面抽取的属性和方法一定是所有子类所共有)
- (Student继承Person,那么Student就是人)
-
面向对象特征:抽象、封装、继承、多态
-
OOP: Object Oriented Programming 面向对象编程
-
UML: 类图(描述类和类之间的关系)
-
Java是单继承,就是一个类只能继承extends(inherit)一个类,而java这中面向对象的语言就是对现实世界的描述,现实世界中是存在很多多继承,但是java里面是支持实现多个接口。 Object是所有类的父类(这个父类不一定是直接父类)
-
访问权限:
- private:只在当前类里面可以访问(子类也不能访问)
- public:任何地方都可以访问
- protected:提高代码复用性。 将所有子类共有的属性和方法抽取到父类里面,子类继承父类,那么父类里面的属性和方法相当于子类里面也有。
-
构造方法不写,java默认加上:
- 无参构造方法(如果写了构造方法,默认的无参口构造方法会被覆盖
- 一个类不继承任何一个类默认继承extends Object
- 在类的构造方法第一句默认会加上super()来调用父类无参的构造方法
-
方法的重载: overload
-
在同一个类里面,允许存在一个以上同名方法,只要他们参数类型和参数个数不同即可(参数列表不同)。
-
构造方法重载(无参构造方法、有参构造方法)
-
方法重载特点:与返回值无关,只看参数列表。
void show(int a, char b, double c){}
void show(int x, char y, double z){} //不是重载,因为方法列表相同
int show(int a, double c, char b){} //是重载,方法头里参数类型不同
void show(int a, double c, char b){} //是重载,方法头里参数类型不同
boolean show(int c, char b){} // 是重载,方法参数个数不同
void show(double c){ } //是重载,方法参数个数、类型不同
double show(int x, char y, double z){} //不是重载
-
方法的重写(覆盖)例如:@Override:toString()
- 子类覆盖父类,必须保证子类权限大于父类权限才可以覆盖,否则会编译失败。
- 如果父类是private的方法,子类是默认方法,那么子类是不知道这个方法的,不是覆盖。
-
重载与重写的区别:
- 重载(Overload): 同一个类中看同名方法的参数列表。(构造方法重载)
- 重写(Override): 父子类方法要一模一样
- 多态: 面向接口(抽象)编程
- 多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Person p = new Child();
Shape shape = new Circle(); shape.draw(); shape = new Square(); shape.draw();
- 抽象类:
- 抽象方法是没有方法体,如果这个类里面有抽象方法,这个类必须变成抽象类。(抽象方法只能存在于抽象类中)
- 如果这个类是抽象类,并不要求这个类一定要有抽象方法 (抽象类里也可以有其他非抽象方法)
- 抽象类里面可以有普通方法,也可以有抽象方法。
- 如果一个类是抽象类,那么这个类就不能被new实例化,只能被其他类继承。
- 抽象方法可以理解为父类(抽象类)定义的一个模板或者规范(自己本身不实现) , 子类必须实现这个类中所有抽象方法, 如果子类不想实现这个方法,那么这个子类也必须要变成抽象类。
- 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
- 接口interface:
-
接口是一个纯粹的抽象类(接口里面所有的方法都是抽象方法) , 接口就是一个规范,他没有提供任何是实现,具体的功能由实现接口的子类去实现。
-
接口就是一个规范,可插拔(可以被替换,首先定义一个标准(接口),大家都遵守这个标准,就可以实现互相之间替换)
-
接口是一个纯粹的抽象类,接口里面的方法都是抽象方法 public abstract。
-
我们不能直接去实例化一个接口,因为接口中的方法都是抽象的,是没有方法体的,这样怎么可能产生具体的实例呢?但是,我们可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。
-
接口中所有的元素都是public修饰的。
-
接口中只包含常量和抽象方法
-
接口中的抽象方法定义时:public abstract修饰符可以省略。
-
接口里面所有的属性public static final ,接口中的常量的public static final可以省略。
- final:最终的意思
- final修饰变量:这个变量就变成常量,不能被修改
- final修饰类:这个类就不能被继承
- final修饰方法:这个方法就不能被重写
举例:白炽灯的接口、计算机主板上CPU、内存
public void test1() {
DaYan daYan = new DaYan();
daYan.egg();
daYan.fly();
daYan.print();
// bird是站在AbstractBird这个类角度去看new出来的DaYan这个对象,
// 所以只能看到egg()这个方法
AbstractBird bird = new DaYan();
bird.egg();
// bird.fly();
// bird.print();
// 站在能不能飞IFly的角度去看DaYan,只能看到fly()这个方法
IFly fly = new DaYan();
fly.fly();
//fly.egg();
//fly.print();
fly = new GeZi();
fly.fly();
}
继承是严格的父子关系,你继承什么你就是什么:鸽子就是鸟。父类是抽取了所有子类的共同特征,父类里面的属性和方法是所有子类所共有的属性和方法。接口是一个标准,一般用在能不能具有某个功能。把能不能飞定义称为一个接口IFly,实现了这个接口的类就具有了这个功能。
- 静态属性、静态方法:
小区里面业主的房子可以看成一个一个的对象,这些都是属于特定的业主所独有。但是小区里面也有一些公共设施(健身器材、绿地),这些公共设施是属于这个小区的。但是是可以被所有的业主对象所使用的。
java类里面定义的静态变量和静态方法是属于这个类的,不属于new出来的Student对象,但是可以被所有的对象所使用,当类加载到内存,静态属性和静态方法就可以调用,这个时候没有new任何对象。
- 使用时应注意:
- 静态的方法只能访问静态的方法和静态的属性(因为当前对象的实例可以没有创建,所以静态的方法是没办法调用非静态的方法和属性的)
- 静态的方法中不能写this、super关键字(因为当前的对象实例可能还没有创建,代表当前类对象的this还有代表父类对象的super可能都还没有创建)
- 非静态的属性和方法(实例属性和方法)必须通过new对象访问,而静态的属性和方法是属于类的,在类加载到内存中就可以访问,被所有对象所共享。



