一、封装
1、介绍
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界的调用,从而提高系统的可扩展性、可维护性。通俗的讲把该隐藏的隐藏起来,该暴露的暴露出来。我们将类的属性私有化 (private),同时提供 公共的(public) 方法 获取(getXXX) 和 设置(setXXX) 值。不对外暴露私有的方法。
2、权限修饰范围
权限修饰符有四个控制范围等级是 private --> default --> protected --> public
。分别的权限控制范围是:private 类内部;default 类内部和同一个包;protected 类内部 同一个包 不同包的子类;public 类內部 同一个包 不同包的子类 同一个项目。
3、作用地方
可以修饰类和类的内部结构:属性、方法、构造器、内部类。4种修饰符能修饰:属性、方法、构造器、内部类。 修饰类的话只能使用:default、public。
二、继承
1、介绍
在Java中,继承是一种面向对象编程(OOP)的特性,它允许我们根据已存在的类来定义一个新的类,这个新类(称为子类或派生类)继承了原有类(称为父类或基类)的属性和方法。通过继承,我们可以重用、扩展或修改继承而来的属性和方法,从而支持代码复用,实现多态和增强软件的可维护性。
2、特点
- 代码复用:通过继承,子类可以复用父类中的代码,包括属性和方法。
- 扩展性:子类可以添加新的属性和方法,或者覆盖(Override)父类中的方法,以实现新的功能或修改原有功能。
- 多态性:继承是实现多态性的基础之一,通过继承,我们可以将父类类型的引用指向子类对象,并通过该引用调用实际子类对象的方法。
- 在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问方式有两种方式:
- 直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上找。
- 间接通过成员方法访问成员变量:该方法属于谁,就优先用谁,没有则向上找。
- 继承关系中重名的关系:
- 局部变量:直接写成员变量名。
- 本类中的成员变量:this.成员变量名。
- 父类中的成员变量:super.成员变量名。
- 在父子类的继承关系中,创建子类对象,访问成员方法的规则:创建的对象是谁,就优先用谁,如果没有就向上找。
- 构造方法:
- 子类构造方法中默认隐含
super()
,所以一定先调用父类的构造,后执行子类的构造。 - 子类构造可以通过
super
关键字来调用父类重载构造。 - super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次
super
构造。 - 子类必须调用父类构造方法,不写则赠送
super()
,写了则用写的指定的的super
调用,super
只能有一个,还必须是第一个。
- 子类构造方法中默认隐含
- 注意事项:
- 无论成员方法和成员变量,都不会向下找。
- 继承是多态的前提。
- 阻止继承的方式是用
final
关键字修饰。
三、多态
1、介绍
多态是同一个行为具有不同的表现形式或形态的能力。一个对象拥有多种形态,这就是多态。代码中体现多态性,其实就是父类引用指向子类对象。
2、多态的前置条件
继承、重写、父类引用指向子类对象。
语法:
//1.定义子类:
public class Demo extends OldClass{
}
//2.继承:
//定义:
public class OldClass{
}
public class Demo extends OldClass{
}
//定义父类的格式:
public class 父类名称 {
// ...
}
//定义子类的格式:
public class 子类名称 extends 父类名称 {
}
//3.多态:
父类名称 对象名 = new 子类名称();
||
接口名称 对象名 = new 实现类名称();
案例:
//4.多态
//Demo01Multi
package com.tsing.extend.demo3;
//代码中体现多态性,其实就是父类引用指向子类对象。
public class Demo01Multi {
public static void main(String[] args) {
//多态写法
//左侧父类的引用指向右侧子类的对象
Fu obj = new Zi();
obj.method();
obj.methodFu();
}
}
//Fu
package com.tsing.extend.demo3;
public class Fu {
public void method() {
System.out.println("父类方法执行");
}
public void methodFu() {
System.out.println("父类特有的方法!!!");
}
}
//Zi
package com.tsing.extend.demo3;
public class Zi extends Fu {
@Override
public void method(){
System.out.println("子类方法执行!!!");
}
}
四、重写和重载
在Java中,重写(Override)和重载(Overload)是面向对象编程中两个非常重要的概念,它们都与方法的定义和调用有关,但两者有着本质的区别。
1、重写(Override)
重写是子类对父类中继承来的方法进行重新定义(也就是方法签名相同,但方法体不同)。当子类需要修改从父类继承来的方法的行为时,就会使用到重写。重写的目的是允许子类提供特定于自己的实现。
重写的规则:
- 方法名、参数列表必须相同:这是为了保持多态性,即父类类型的引用可以指向子类对象,并调用实际子类对象的方法。
- 返回类型:对于非静态方法,返回类型可以是父类方法的返回类型的子类型(Java 5及以后版本支持协变返回类型)。对于静态方法,返回类型必须相同。
- 访问修饰符:子类方法的访问级别不能低于父类方法的访问级别(但可以有更高的访问级别)。
- 异常:子类方法抛出的异常应该是父类方法抛出异常的子类或没有异常(Java 7及以后版本支持更灵活的异常处理规则)。
示例:
class Animal {
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
@Override
void eat() {
System.out.println("Dog eats dog food.");
}
}
在这个例子中,Dog
类重写了Animal
类的eat
方法。
2、重载(Overload)
重载是在同一个类中,允许存在多个同名的方法,只要它们的参数列表不同即可。参数列表不同意味着参数的数量、类型或顺序至少有一项不同。重载的主要目的是提供灵活的方法调用,允许根据传递的参数类型或数量来调用不同的方法实现。
重载的规则:
- 方法名必须相同。
- 参数列表必须不同(参数的数量、类型或顺序不同)。
- 方法的返回类型、访问修饰符以及抛出的异常类型与重载无关。
示例:
class MathUtils {
// 方法1
int add(int a, int b) {
return a + b;
}
// 方法2,重载
double add(double a, double b) {
return a + b;
}
// 方法3,重载(参数数量不同)
int add(int a, int b, int c) {
return a + b + c;
}
}
在这个例子中,MathUtils
类有三个名为add
的方法,但它们的参数列表不同,因此它们是重载关系。
总结
- 重写是子类对父类方法的重新定义,用于提供特定于子类的实现。
- 重载是在同一个类中允许存在多个同名但参数列表不同的方法,用于提供灵活的方法调用。
- 重写是面向对象多态性的体现,而重载是编译时多态性的体现。