java-OOP核心:封装、继承、多态、接口和抽象类、内部类
1、封装(Encapsulation)
-
怎么做:属性用
private修饰,提供public的getter/setter。 -
为什么做:保护数据不被随意修改,你可以在
setter里加校验逻辑(比如年龄不能为负)
// 父类:Animal public class Animal { // 1. 封装属性:用 private 修饰,外部不能直接访问 private String name; // 2. 提供公共的 getter/setter 来访问属性 public String getName() { return name; } public void setName(String name) { if (name != null && !name.isEmpty()){ //判断name是否为空 this.name = name; } else{ System.out.println("name不能为空!"); } } // 3. 定义一个“发声”的方法(具体怎么叫,由子类去实现) public void makeSound() { System.out.println("动物发出了某种声音..."); } }
2、继承(Inheritance)
-
语法:
class 子类 extends 父类。 - 为什么做:复用代码实现扩展子类的功能。
-
子类获取的:父类的
public和protected成员,private的成员也被继承、但因不可见而无法直接访问。 -
super关键字:访问父类成员、调用父类构造方法(
super()必须是第一句)。- super.父类成员:访问当前对象的父类的成员。
- this.成员:访问当前对象的成员。
- super():调用父类的构造方法(必须写在第一行),默认编译器会自动加一个
super()调用父类无参构造。- 创建子类对象:必须先完成父类对象的初始化(即先调用父类构造方法),再初始化子类自己的部分(再调用子类的构造方法)。
- 创建子类对象:必须先完成父类对象的初始化(即先调用父类构造方法),再初始化子类自己的部分(再调用子类的构造方法)。
- this():调用本类的其他构造方法,复用本类的初始化逻辑(this()和super()只能二选一,两个最终都一定会先执行到父类的构造方法)。
- super.父类成员:访问当前对象的父类的成员。
-
方法重写(Override):子类重新定义父类方法。注解
@Override建议写上,可以检查是否写错。 -
一个关键限制:Java是单继承(一个类只能有一个父类),但可以实现多个接口。
// 子类:Cat 继承 Animal public class Cat extends Animal { // 重写父类的 makeSound 方法 @Override public void makeSound() { // 调用父类的 getName() 方法(因为name是private,通过getter访问) System.out.println(getName() + " 喵喵叫~~"); } } // 子类:Dog 继承 Animal public class Dog extends Animal { @Override public void makeSound() { System.out.println(getName() + " 汪汪叫!!"); } }
3、多态(Polymorphism)
-
含义:同一个行为,不同对象表现出不同形态。比如猫叫声是喵,狗叫声是汪。
-
实现条件:继承 + 重写方法 + 父类引用指向子类对象(
Parent p = new Child();)。- 父类引用访问重写方法,实际是访问子类重写后的版本
- 父类引用:不能访问子类特有的成员(子类有、父类没有),通过向下转型才可以访问子类特有的成员
if (animal instanceof Cat) { //判断animal是否是Cat(包括Cat子类)的实例, Cat myCat = (Cat) animal; // 向下转型 myCat.play(); // 现在可以调用Cat特有的play()方法 }
-
好处:让代码更灵活,比如方法参数写成父类类型,就能接收所有子类对象。
public class TestPolymorphism { public static void main(String[] args) { // 1. 创建具体的猫和狗对象 Cat cat = new Cat(); cat.setName("小花"); // 使用继承自父类的方法 Dog dog = new Dog(); dog.setName("旺财"); // 2. 多态:用父类引用指向子类对象 Animal animal1 = cat; // 自动向上转型 Animal animal2 = dog; // 3. 调用同一个方法,但执行的行为完全不同! // 实际执行的是子类重写后的版本 animal1.makeSound(); // 输出:小花 喵喵叫~~ animal2.makeSound(); // 输出:旺财 汪汪叫!! // 4. 多态的妙用:一个方法可以处理所有动物 makeAnimalSound(cat); // 传入子类对象 makeAnimalSound(dog); } // 这个方法只依赖 Animal 父类,但能接收所有子类 public static void makeAnimalSound(Animal animal) { animal.makeSound(); // 具体执行哪个版本,由传入的对象类型决定 } }
4、接口和抽象类
参考:接口和抽象类介绍
5、内部类
- 内部类是定义在类内部的类,分为四种:成员内部类、静态内部类、局部内部类、匿名内部类;
- 为什么需要内部类:间接实现多继承(内部类可以继承另一个类)、提供更好的封装、回调处理等。
|
成员内部类(非静态) 可以访问外部类的所有成员(包括私有); 创建时需要外部类实例; |
public class Outer { private String outerField = "外部类属性"; // 成员内部类 class MemberInner { void display() { System.out.println("访问:" + outerField); // 可以访问私有属性 } } public static void main(String[] args) { // 创建方式:先创建外部类对象,再通过它创建内部类对象 Outer outer = new Outer(); MemberInner inner = outer.new MemberInner(); inner.display(); } }
|
|
静态内部类 用 创建时不需要外部类实例; |
public class Outer { private static String staticField = "静态外部类属性"; private String Field = "外部类属性"; // 静态内部类 static class StaticInner { void display() { System.out.println("访问:" + staticField); // 只能访问外部类的静态成员 System.out.println("访问:" + Field); // 访问非静态成员,会报错 } } public static void main(String[] args) { // 创建方式:直接 new,不需要外部类实例 StaticInner inner = new StaticInner(); inner.display(); } }
|
|
局部内部类 定义在方法内部; 作用域仅限于该方法;可以访问外部类的成员,以及方法的 |
public class Outer { private String outerField = "外部类属性"; void method() { String localVar = "有效final局部变量"; // 有效final(从未被重新赋值的局部变量) final String localString = "final局部变量" ; //final变量 // 局部内部类 class LocalInner { void display() { System.out.println("访问:" + outerField); // 可以访问外部类成员 System.out.println("访问:" + localVar); |
|
匿名内部类 没有名字,多用于实现接口或继承类; |
public class Outer { // 传入Runnable对象,调用Runnable对象的run() void execute(Runnable task) { task.run(); } public static void main(String[] args) { Outer outer = new Outer(); // 匿名内部类:new 接口/类() { ... },new的是接口的实现类 // 用匿名内部类 实现 Runnable 接口 outer.execute(new Runnable() { @Override public void run() { System.out.println("匿名内部类执行了"); } }); // 也可以用来继承抽象类或普通类(写法类似) // Thread t = new Thread() { ... }; } }
|
本文来自博客园,作者:FengweiTech,转载请注明原文链接:https://www.cnblogs.com/fengwei-blogs/p/22201063

浙公网安备 33010602011771号