面向对象 - 封装
-- 前面的学习思想都是面向过程编程,现在开始学习 面向对象编程
-- 什么是对象? 对象:特殊的数据结构,用来记住一个事物的数据,从而代表该事物
-- Tips:对象就是实例,实例就是对象。
快速入门
第一步:设计对象的模板【设计图】:类(类是对象的抽象,用来描述一组对象的共同特征)
- 类中可以定义成员变量、成员方法
成员变量 | 类中定义的变量 |
局部变量 | 方法中定义的变量 |
// 定义一个student类
public class Student {
// 类中可以定义:成员变量、成员方法。【非私有成员:成员变量、成员方法】
// ① 成员变量:定义在类中的变量
// ② 局部变量:定义在方法中的变量
// 成员变量:又称对象的属性,描述对象的特征
String name; // 姓名
int age; // 年龄
String sex; // 性别
int chinese; // 语文成绩
int math; // 数学成绩
// 成员方法:描述对象的行为
public void sum(){
int sum;
sum = chinese + math;
System.out.println("总分:" + sum);
}
public void avg(){
System.out.println("平均分:" + (chinese + math) / 2);
}
}
第二步:每new一次类,就得到一个新对象
public class Test1 {
public static void main(String[] args) {
Student s1 = new Student(); // 创建Student对象
s1.name = "张三";
s1.age = 18;
s1.sex = "男";
s1.chinese = 100;
s1.math = 45;
System.out.println(s1.name + " " + s1.age + " " + s1.sex);
s1.sum();
s1.avg();
Student s2 = new Student(); // 创建Student对象
s2.name = "李四";
s2.age = 19;
s2.sex = "女";
s2.chinese = 87;
s2.math = 100;
System.out.println(s2.name + " " + s2.age + " " + s2.sex);
s2.sum();
s2.avg();
}
}
类的用法 - 构造器
-- 构造器:特殊的方法。名称必须和类名相同
-- 【例如】类名为Student,那么定义的构造器必须也为Student
-- 构造器的应用场景:创建对象时,为 对象成员变量的初始化赋值。
-- 构造器的特点:
-- 1. 构造器的名称必须与类名相同
-- 2. 构造器不能有返回值类型(包括也不能写void)
-- 3. 构造器可以重载,可以定义多个
-- 4. 创建对象时自动调用构造器
-- 5. 类默认自带一个无参构造器,默认调用
-- 6. 如果定义了有参构造器,那默认的无参构造器就没了,若想用无参构造器,需要重新定义
public class Student { String name; // 姓名 int age; // 年龄 char sex; // 性别 // 构造器:无参构造器 public Student() { System.out.println("无参构造器被调用了!"); } // 构造器:有参构造器 public Student(String n, int a, char s) { System.out.println("有参构造器(完整)被调用了!"); name = n; age = a; sex = s; } // 构造器:有参构造器 public Student(String n){ name = n; System.out.println("有参构造器(部分)被调用了!"); } }
public class Test1 { public static void main(String[] args) { Student s1 = new Student("张三", 18, '男'); Student s2 = new Student(); Student s3 = new Student("李四"); } } // 输出如下: // 有参构造器(完整)被调用了!!! // 无参构造器被调用了!!! // 有参构造器(部分)被调用了!!!
类的用法 - this
类的用法 - 封装
面向对象编程的三大特征:封装、继承、多态
类就是一种封装
封装的设计思想:合理隐藏、合理暴露
类的用法 - 实体类 javabean
实体类:特殊的类。必须满足以下
- 类中的成员变量全部私有,并提供public修饰的getter/setter方法
- 类中必须有无参构造器。有参构造器可选
- 【实体类的应用场景】实体类的对象只负责数据存取,而对数据的业务处理交给其他类的对象去完成,以实现数据和数据业务处理 分离。
// 以下是一个标准的实体类: public class Student { // 封装的思想:将属性私有化(provite),通过方法访问属性 // 1.属性私有化。作用:封装属性,避免属性被修改 private String name; private int age; private char sex; private double chinese; private double math; // 2.提供getter和setter方法。 // set:设置属性值 // get:获取属性值 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public double getChinese() { return chinese; } public void setChinese(double chinese) { this.chinese = chinese; } public double getMath() { return math; } public void setMath(double math) { this.math = math; } // 提供一个无参构造器 public Student() {} // 提供一个有参构造器(可选) public Student(String name, int age, char sex, double chinese, double math) { this.name = name; this.age = age; this.sex = sex; this.chinese = chinese; this.math = math; } }
类的用法 - static
static:静态的。可以修饰 成员变量、成员方法。
成员变量按有无static修饰,分:类变量、实例变量。
|
成员方法按有无static修饰,分:类方法、实例方法
|
类变量的应用场景:
类方法的应用场景:类方法常用作工具类【工具类:工具类中的方法都是类方法,每个方法用来完成一个功能,工具类是给开发人员共同使用的】
问答题:为什么工具类中的方法用类方法,而不用实例方法?
回答:① 实例方法需要创建对象来调用,创建这个对象只是为了调用方法,对象占内存,这样会浪费内存。② 类方法,直接用类名调用即可,能节省内存。
面向对象 - 继承 extends
继承 - 基础
- 子类继承父类的 非私有成员(成员变量、成员方法)。
- 子类对象由子类、父类共同创建。
- 使用继承的好处:减少重复代码,提高代码复用性。
-
Java是单继承的,类不支持多继承,但支持多层继承。
面试题:为什么类不支持多继承? 反证:假设A类、B类有同名的方法(功能不同),则会冲突
-
object 类:java所有类的祖宗类。任何一个类都是object的子类(或子孙类)
权限修饰符
权限修饰符:限制类中的(成员变量、成员方法、构造器…)能被访问的范围。
限制能被访问的范围 | |
private | 本类 |
缺省 | 本类、同一包下的类 |
protected | 本类、同一包下的类、子孙类 |
public | 任意范围 |
方法重写
当父类的方法不能满足子类的需求时,子类重写一个方法名、参数列表一样的方法,就是方法重写
注:重写后,Java遵循就近原则来访问方法 。
// 方法重写的注意事项
// 1. 重写方法时,加上@Override注解,他可以指定java编译器,检查方法重写的格式是否正确,代码可读性也更好。
// 2. 子类重写父类方法时,访问权限必须大于或等于父类该方法的权限
// 3. 重写方法的返回值类型,要与原方法相同,或范围更小。
// 4. 私有方法、静态方法不能重写,重写会报错。
public class ChongXie02 {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.shout(); // 输出: 汪汪汪!!!
}
}
class Dog extends Animal{
// 重写Animal父类中的 shout 方法
@Override
public void shout(){
System.out.println("汪汪汪!!!");
}
}
class Animal{
// 叫声的方法
public void shout(){
System.out.println("动物会叫~~");
}
}
方法重写 - 拓展:重写object类的tostring方法(重点)
public class ChongXie01 {
public static void main(String[] args) {
Student s1 = new Student("刘思", 18, '女');
System.out.println(s1); // 输出:com.HAF.JiCheng.Student@1b6d3586
// 直接输出对象时,默认调用OBject父类的toString方法(可以省略不写调用toString的代码),返回对象的地址信息
// System.out.println(s1.toString);
// 输出对象的地址实际上没有意义,开发中更希望输出对象的内容信息,所以子类要重写0bject的toString方法,
}
}
class Student {
String name;
int age;
char sex;
// 重写toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
// 生成get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
// 无参构造器
public Student() {}
// 全参构造器
public Student(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
子类中访问其他成员的特点
在子类方法中访问其他成员(成员变量、成员方法):依照就近原则。
- 先子类局部范围找。 然后子类成员范围找。 然后父类成员范围找,仍没有找到则报错。
如果子类和父类,出现重名成员,会优先用子类的,若此时要在子类中使用父类的怎么办?
- 可以通过super关键字,指定访问父类的成员:super.父类成员变量/父类成员方法
public class JiCheng01 {
public static void main(String[] args) {
Student1 s1 = new Student1();
s1.show();
}
}
class People{
String name = "父类";
}
class Student1 extends People{
String name = "子类";
public void show(){
String name = "局部变量";
System.out.println(name); // 输出:局部变量
System.out.println(this.name); // 输出:子类
System.out.println(super.name); // 输出:父类
// this.name:表示当前对象的成员变量
// super.name:表示父类的成员变量
}
}
面向对象 - 多态
多态 - 基础
什么是多态? 多态是在继承/实现后的一种现象,表现为对象多态、行为多态
面向对象 (高级)
final
final:最终的,不可改变的。可以修饰 类、方法、变量
final 修饰的类:称为最终类 | inal 修饰的方法:称为最终方法 | final 修饰的变量 |
不能被继承 | 不能被重写 | 只能赋值一次 |
- final 修饰基本类型的变量,赋值后不可改变。
- final 修饰引用类型的变量,变量存储的地址不能改变,但地址所指向对象的内容可以改变
拓展:final的使用场景:工具类(工具类用final修饰更规范)
抽象类、接口(特殊的抽象类)
-- 抽象类
-- abstract:抽象。可以修饰 类、方法
-- abstract 修饰的类:抽象类。
-- abstract 修饰的方法:抽象方法。
-- 【抽象类的特点】
-- 1. 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。
-- 2. 类该有的成员(成员变量、方法、构造器),抽象类也可以有。
-- 3. 抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现。
-- 4. 一个类继承抽象类后,必须重写抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
-- 接口:特殊的抽象类,接口内只能定义常量和抽象方法
-- 【语法】
-- public interface 接口名{
-- 常量
-- 抽象方法
-- }
-- 接口是用来被类实现的(也就是被类继承)。实现接口的类称为实现类
-- 一个类能实现多个接口(接口就是干爹),一个接口可被多个类实现(类可以理解成干儿子)。
-- 实现类实现多个接口,必须重写每个接口的所有抽象方法,否则必须将实现类定义成抽象类。
-- 【接口的特点】
-- 1. 接口不能有构造方法,不能创建对象
-- 2. 接口不能有成员变量,只能有常量(默认是public static final)
-- 3. 接口内的方法都是抽象方法(默认是public abstract)
-- 4. 接口可以继承接口,接口可以多继承
-- 5. 接口不能有静态代码块和构造代码块
-- 【接口的好处】
-- 1. 弥补类单继承的不足,类可以同时实现多个接口。
-- 2. 让程序面向接口编程,这样就不用关心实现细节,也可以灵活方便的切换各种实现。
1. 定义一个接口
// 接口
public interface JieKou01 {
// 定义一个常量
public static final int TEST_NUM = 10;
// 定义一个抽象方法
public abstract void test();
}
2. 定义一个类(实现上面的接口)。实现接口后的类:称 实现类
// 实现类:实现接口的类称为实现类
public class JieKou_ShiXianLei implements JieKou01{
// 重写接口的所有抽象方法
@Override
public void test(){
System.out.println("重写接口的所有抽象方法");
}
}
内部类
内部类:如果一个类定义在另一个类的内部,则这个类是内部类。
枚举
泛型
常用API
API:应用程序编程接口。就是别人写好的程序,程序员可以直接调用,以解决问题。