一、面向对象的思想
(一)核心概念
- 定义:面向对象是符合人类思维习惯的编程思想,通过对象映射现实事物,用对象关系描述事物联系,将问题划分为独立对象,通过调用对象方法解决问题。
- 核心优势:代码维护更便捷,功能变动时仅需修改相关对象,无需整体调整。
(二)三大特性
- 封装性:将对象的属性和行为视为整体封装,同时隐藏无需外界知晓的信息,仅暴露必要接口。
- 继承性:描述类与类的关系,子类可继承父类的特性和功能,并扩展自身特有功能,提升代码复用性。
- 多态性:子类继承父类后,同名属性或方法可表现出不同行为,使程序更抽象灵活。
(三)编程案例(思想体现)
// 用对象映射现实中的"学生"事物,体现面向对象思想
class Student {
// 封装属性(特征)
String name;
int age;
// 封装方法(行为)
void study() {
System.out.println(name + "正在学习,体现面向对象的封装特性");
}
}
public class OOPDemo {
public static void main(String[] args) {
// 创建对象,映射具体学生
Student stu = new Student();
stu.name = "张三";
stu.age = 18;
// 调用对象方法,通过对象解决问题
stu.study(); // 输出:张三正在学习,体现面向对象的封装特性
}
}
二、类与对象
(一)类的定义
- 概念:类是对象的抽象,描述一组对象的共同特征(成员变量)和行为(成员方法),是创建对象的模板。
- 语法格式:
class 类名 {
成员变量; // 描述特征
成员方法; // 描述行为
}
- 编程案例:
// 定义"手机"类,描述手机的共同特征和行为
class Phone {
// 成员变量(属性)
String brand; // 品牌
String color; // 颜色
int price; // 价格
// 成员方法(行为)
void call() {
System.out.println(brand + "手机正在打电话");
}
void sendMessage() {
System.out.println(brand + "手机正在发短信");
}
}
(二)对象的创建与使用
- 创建格式:
类名 对象名 = new 类名();(分为声明对象和实例化对象两步)。
- 访问方式:通过
对象名.属性名访问成员变量,对象名.方法名()调用成员方法。
- 编程案例:
public class ObjectCreateDemo {
public static void main(String[] args) {
// 创建手机对象
Phone myPhone = new Phone();
// 访问成员变量并赋值
myPhone.brand = "华为";
myPhone.color = "黑色";
myPhone.price = 4999;
// 调用成员方法
myPhone.call(); // 输出:华为手机正在打电话
myPhone.sendMessage(); // 输出:华为手机正在发短信
// 创建第二个对象,独立存储数据
Phone yourPhone = new Phone();
yourPhone.brand = "苹果";
yourPhone.call(); // 输出:苹果手机正在打电话
}
}
(三)对象的引用传递
- 概念:类是引用数据类型,引用传递是多个栈内存指向同一个堆内存空间,共享对象资源。
- 核心特点:修改一个引用变量对应的堆内存数据,其他引用变量访问到的内容会同步变化。
- 编程案例:
class Book {
String bookName;
int pageNum;
}
public class ReferenceDemo {
public static void main(String[] args) {
// 创建对象,stu1指向堆内存
Book book1 = new Book();
book1.bookName = "Java编程基础";
book1.pageNum = 300;
// 引用传递,book2与book1指向同一堆内存
Book book2 = book1;
book2.pageNum = 350; // 修改book2的属性
// 两个引用访问到的数据一致
System.out.println("book1的页数:" + book1.pageNum); // 输出:350
System.out.println("book2的页数:" + book2.pageNum); // 输出:350
}
}
(四)访问控制权限
- 四种权限:private(私有)、default(默认)、protected(受保护)、public(公共),权限从左到右依次增大。
- 访问范围:
- private:仅本类可访问
- default:本类+同一包中的类可访问
- protected:本类+同一包+不同包的子类可访问
- public:所有类可访问
- 编程案例:
class Person {
public String name; // 公共权限,所有类可访问
protected int age; // 受保护权限,子类和本包可访问
String gender; // 默认权限,本包可访问
private String idCard; // 私有权限,仅本类可访问
// 私有属性的访问接口
public void setIdCard(String id) {
idCard = id;
}
public String getIdCard() {
return idCard;
}
}
public class AccessControlDemo {
public static void main(String[] args) {
Person p = new Person();
p.name = "李四"; // 允许访问public属性
p.age = 25; // 允许访问protected属性
p.gender = "男"; // 允许访问default属性
// p.idCard = "123456"; // 报错,private属性不可直接访问
p.setIdCard("123456789");
System.out.println("身份证号:" + p.getIdCard()); // 输出:123456789
}
}
三、封装性
(一)封装的意义
- 核心目的:保护对象的属性不被随意修改,避免不合理数据录入,同时隐藏实现细节,仅通过指定接口交互。
- 问题场景:直接访问对象属性可能导致无效数据(如年龄赋值为负数),封装可解决此问题。
(二)封装的实现步骤
- 私有化成员变量:用
private修饰属性,禁止外界直接访问。
- 提供公共访问接口:定义
getXxx()方法(获取属性值)和setXxx()方法(设置属性值),在方法中添加数据校验逻辑。
(三)编程案例
class User {
// 私有化成员变量,禁止外界直接访问
private String username;
private int age;
// 提供setter方法,设置属性并校验
public void setUsername(String name) {
// 简单校验:用户名不为空
if (name != null && !name.equals("")) {
username = name;
} else {
System.out.println("用户名不能为空");
}
}
public void setAge(int a) {
// 校验:年龄在合理范围
if (a >= 0 && a <= 120) {
age = a;
} else {
System.out.println("年龄输入有误");
}
}
// 提供getter方法,获取属性值
public String getUsername() {
return username;
}
public int getAge() {
return age;
}
}
public class EncapsulationDemo {
public static void main(String[] args) {
User user = new User();
user.setUsername(""); // 输出:用户名不能为空
user.setAge(-18); // 输出:年龄输入有误
user.setUsername("赵六");
user.setAge(22);
System.out.println("用户名:" + user.getUsername() + ",年龄:" + user.getAge());
// 输出:用户名:赵六,年龄:22
}
}
四、构造方法
(一)构造方法的定义
- 核心特征:名称与类名一致,无返回值类型声明,实例化对象时自动调用。
- 语法格式:
class 类名 {
修饰符 类名(参数列表) {
构造体;
}
}
- 编程案例:
class Dog {
String name;
int age;
// 无参构造方法
public Dog() {
System.out.println("调用无参构造方法");
}
// 有参构造方法
public Dog(String n, int a) {
name = n;
age = a;
System.out.println("调用有参构造方法");
}
void bark() {
System.out.println(name + "在叫,年龄:" + age);
}
}
public class ConstructorDemo {
public static void main(String[] args) {
Dog dog1 = new Dog(); // 调用无参构造
Dog dog2 = new Dog("旺财", 3); // 调用有参构造
dog2.bark(); // 输出:旺财在叫,年龄:3
}
}
(二)构造方法的重载
- 定义:同一类中,多个构造方法名称相同,参数个数或类型不同。
- 核心规则:通过不同参数列表区分,实例化时根据传入参数自动匹配。
- 编程案例:
class Cat {
String name;
int age;
String color;
// 无参构造
public Cat() {}
// 一个参数构造
public Cat(String n) {
name = n;
}
// 两个参数构造
public Cat(String n, int a) {
name = n;
age = a;
}
// 三个参数构造
public Cat(String n, int a, String c) {
name = n;
age = a;
color = c;
}
void show() {
System.out.println("姓名:" + name + ",年龄:" + age + ",颜色:" + color);
}
}
public class ConstructorOverloadDemo {
public static void main(String[] args) {
Cat cat1 = new Cat("咪咪");
Cat cat2 = new Cat("花花", 2, "橘色");
cat1.show(); // 输出:姓名:咪咪,年龄:0,颜色:null
cat2.show(); // 输出:姓名:花花,年龄:2,颜色:橘色
}
}
(三)默认构造方法
- 规则:类中未定义构造方法时,系统自动提供无参默认构造;若定义了构造方法,系统不再提供。
- 注意事项:定义有参构造后,建议手动添加无参构造,避免实例化时报错。
五、this关键字
(一)调用本类属性
- 作用:区分成员变量与局部变量同名问题,明确引用当前对象的成员变量。
- 编程案例:
class Teacher {
private String name;
private int age;
public Teacher(String name, int age) {
this.name = name; // this引用成员变量
this.age = age;
}
void introduce() {
System.out.println("我是" + this.name + ",年龄" + this.age);
}
}
public class ThisAttrDemo {
public static void main(String[] args) {
Teacher t = new Teacher("王老师", 35);
t.introduce(); // 输出:我是王老师,年龄35
}
}
(二)调用本类方法
- 作用:在类的成员方法中调用本类其他成员方法,可省略this,增强代码可读性。
- 编程案例:
class Cook {
public void wash() {
System.out.println("洗菜");
}
public void cut() {
System.out.println("切菜");
}
public void cook() {
this.wash(); // 调用本类wash方法
this.cut(); // 调用本类cut方法
System.out.println("炒菜");
}
}
public class ThisMethodDemo {
public static void main(String[] args) {
Cook c = new Cook();
c.cook();
// 输出:洗菜 → 切菜 → 炒菜
}
}
(三)调用本类构造方法
- 语法:
this(参数列表),只能在构造方法中使用,且必须位于第一行。
- 注意事项:不能相互调用,避免死循环。
- 编程案例:
class Car {
String brand;
int price;
// 无参构造
public Car() {
this("未知品牌", 0); // 调用有参构造
System.out.println("调用无参构造");
}
// 有参构造
public Car(String b, int p) {
brand = b;
price = p;
System.out.println("调用有参构造");
}
}
public class ThisConstructorDemo {
public static void main(String[] args) {
Car car = new Car();
// 输出:调用有参构造 → 调用无参构造
}
}
六、代码块
(一)普通代码块
- 定义:直接在方法中定义的代码块,用于限定变量作用域,避免命名冲突。
- 编程案例:
public class CommonBlockDemo {
public static void main(String[] args) {
{
int num = 10;
System.out.println("普通代码块:" + num); // 输出:10
}
// System.out.println(num); // 报错,num作用域仅在代码块内
int num = 20;
System.out.println("main方法:" + num); // 输出:20
}
}
(二)构造块
- 定义:直接在类中定义的代码块,无关键字修饰,实例化对象时执行,且优先于构造方法。
- 核心特点:每次实例化对象都会执行一次。
- 编程案例:
class Flower {
// 构造块
{
System.out.println("执行构造块");
}
public Flower() {
System.out.println("执行构造方法");
}
}
public class ConstructorBlockDemo {
public static void main(String[] args) {
Flower f1 = new Flower();
Flower f2 = new Flower();
// 输出:执行构造块 → 执行构造方法 → 执行构造块 → 执行构造方法
}
}
七、static关键字
(一)静态属性
- 概念:用static修饰的属性,属于类级别的属性,所有对象共享,存储在全局数据区。
- 访问方式:
类名.属性名(推荐)或对象名.属性名。
- 编程案例:
class School {
String name;
static String country = "中国"; // 静态属性,所有对象共享
public School(String n) {
name = n;
}
}
public class StaticAttrDemo {
public static void main(String[] args) {
School s1 = new School("北京大学");
School s2 = new School("清华大学");
System.out.println(s1.name + ",所在国家:" + School.country);
System.out.println(s2.name + ",所在国家:" + School.country);
School.country = "中华人民共和国"; // 修改静态属性
System.out.println("修改后:" + s1.country); // 所有对象共享修改后的值
}
}
(二)静态方法
- 概念:用static修饰的方法,属于类级别,无需实例化对象即可调用。
- 注意事项:只能访问静态成员,不能访问非静态成员和this关键字。
- 编程案例:
class MathTool {
// 静态方法
public static int add(int a, int b) {
return a + b;
}
public static int multiply(int a, int b) {
return a * b;
}
}
public class StaticMethodDemo {
public static void main(String[] args) {
// 直接通过类名调用静态方法
int sum = MathTool.add(3, 5);
int product = MathTool.multiply(4, 6);
System.out.println("和:" + sum + ",积:" + product);
}
}
(三)静态代码块
- 定义:用static修饰的代码块,类加载时执行一次,常用于初始化静态属性。
- 执行顺序:静态代码块 → 构造块 → 构造方法。
- 编程案例:
class Star {
static String type;
// 静态代码块
static {
type = "恒星";
System.out.println("执行静态代码块,初始化type属性");
}
{
System.out.println("执行构造块");
}
public Star() {
System.out.println("执行构造方法");
}
}
public class StaticBlockDemo {
public static void main(String[] args) {
Star sun = new Star();
Star moon = new Star();
// 输出:执行静态代码块 → 执行构造块 → 执行构造方法 → 执行构造块 → 执行构造方法
}
}