Dog dog = new Dog();
dog.setName(“张三”);
dog.setWeight(30f);
// 调用继承自父类的公有方法
dog.eat();
// 调用其特有方法
dog.run();
// 实例化一个宠物猫
Cat cat = new Cat();
cat.setName(“豆豆”);
// 调用继承自父类的公有方法
cat.eat();
// 调用其特有方法
cat.sleep();
运行结果:
张三在吃东西
胖成了30.0斤的狗子张三在奔跑
豆豆在吃东西
豆豆睡大觉zzz
3.1 概念
如果一个类从它的父类继承了一个方法,如果这个方法没有被标记为 final
或 static
,就可以对这个方法进行重写。重写的好处是:能够定义特定于子类类型的行为,这意味着子类能够基于要求来实现父类的方法。
3.2 实例
在上述父类 Pet
中有一个 shout
方法,我们知道小猫和小狗的叫声是不同的,此时可以使用方法重写,在 Dog
类和 Cat
类中重写 shout
方法。
Dog 类:
class Dog extends Pet{
// 重写 shout 方法
public void shout() {
System.out.println(this.getName() + “汪汪汪地叫~”);
}
}
Cat 类:
class Cat extends Pet{
@Override // 使用注解
public void shout() {
System.out.println(this.getName() + “喵喵喵地叫~”);
}
}
Tips:在要重写的方法上面,可以选择使用
@Override
注解,让编译器帮助检查是否进行了正确的重写。如果重写有误,编译器会提示错误。虽然这个注解不是必须的,但建议日常编码中,在所有要重写的方法上都加上@Override
注解,这样可以避免我们由于马虎造成的错误。
在IDEA里只要和父类方法名一致,就会自动生成
@Overvide
修饰符,意思是对父类的方法进行重写
可以使用对象实例调用其重写的方法:
// 实例化一个宠物狗
Dog dog = new Dog();
dog.setName(“欢欢”);
// 调用重写方法
dog.shout();
// 实例化一个宠物猫
Cat cat = new Cat();
cat.setName(“豆豆”);
// 调用重写方法
cat.shout();
运行结果:
张三汪汪汪地叫~
豆豆喵喵喵地叫~
3.3 方法重写规则
关于方法重写,有以下规则:
-
重写方法的参数列表应该与原方法完全相同;
-
返回值类型应该和原方法的返回值类型一样或者是它在父类定义时的子类型;
-
重写方法访问级别限制不能比原方法高。例如:如果父类方法声明为公有的,那么子类中的重写方法不能是私有的或是保护的。具体限制级别参考访问修饰符;
-
只有被子类继承时,方法才能被重写;
-
方法定义为
final
,将不能被重写; -
一个方法被定义为 static,将使其不能被重写,但是可以重新声明;
-
一个方法不能被继承,那么也不能被重写;
-
和父类在一个包中的子类能够重写任何没有被声明为 private 和 final 的父类方法;
-
和父类不在同一个包中的子类只能重写 non-final 方法或被声明为 public 或 protected 的方法;
-
一个重写方法能够抛出任何运行时异常,不管被重写方法是否抛出异常。然而重写方法不应该抛出比被重写方法声明的更新更广泛的已检查异常。重写方法能够抛出比被重写方法更窄或更少的异常;
-
构造方法不能重写。
3.4 方法重写和方法重载的区别
Java 中的方法重写(Overriding
)是说子类重新定义了父类的方法。方法重写必须有相同的方法名,参数列表和返回类型。覆盖者访问修饰符的限定大于等于父类方法。
而方法重载(Overloading
)发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。
4.1 作用
我们使用 private
和 public
两种访问修饰符实现了对类的封装。现在终于到了详细了解访问修饰符的时候了。
为了实现对类的封装和继承,Java 提供了访问控制机制。通过访问控制机制,类的设计者可以掩盖变量和方法来达到维护类自身状态的目的,而且还可以将另外一些需要暴露的变量和方法提供给别的类进行访问和修改。
4.2 种类
Java 一共提供了 4 种访问修饰符:
-
private:私有的,只允许在本类中访问;
-
protected:受保护的,允许在同一个类、同一个包以及不同包的子类中访问;
-
默认的:允许在同一个类,同一个包中访问;
-
public:公共的,可以再任何地方访问。
下表按照限定能力从大到小列出了访问修饰符在不同作用域的作用范围:
| 访问控制修饰符 | 同一个类 | 同一个包 | 不同包的子类 | 不同包的非子类 |
| :-- | :-- | :-- | :-- | :-- |
| private(私有的) | ✓ | ✕ | ✕ | ✕ |
| default(默认的) | ✓ | ✓ | ✕ | ✕ |
| protected(受保护的) | ✓ | ✓ | ✓ | ✕ |
| public(公共的) | ✓ | ✓ | ✓ | ✓ |
super
是用在子类中的,目的是访问直接父类的变量或方法。注意:
-
super 关键字只能调用父类的
public
以及protected
成员; -
super 关键字可以用在子类构造方法中调用父类构造方法;
-
super 关键字不能用于静态 (
static
) 方法中。
5.1 调用父类构造方法
父类的构造方法既不能被继承,也不能被重写。
可以使用 super
关键字,在子类构造方法中要调用父类的构造方法,语法为:
super(参数列表)
例如,父类 Pet
中存在构造方法:
package com.caq.oop.demo03;
public class Pet {
public Pet(String name) {
System.out.println(“名字为”+name);
}
}
子类 Cat
的构造方法中调用父类构造方法:
package com.caq.oop.demo03;
public class Cat extends Pet {
//子类 Cat
的构造方法中调用父类构造方法
public Cat(String name) {
super(name);
System.out.println(“调用父类的构造方法调用成功!”);
}
public static void main(String[] args) {
new Cat(“旺财”);
}
}
调用 Dog
有参构造方法,进行实例化:
new Dog(“花花”);
运行结果:
宠物实例被创建了,宠物名字为花花
小狗实例被创建了
5.2 调用父类属性
子类中可以引用父类的成员变量,语法为:
super.成员变量名
例如,在 Dog 类中调用父类的成员变量 birthday
:
class Pet {
protected String birthday;
}
class Dog extends Pet {
public Dog() {
System.out.println(“宠物生日:” + super.birthday);
}
}
5.3 调用父类方法
有时候我们不想完全重写父类方法,可以使用 super
关键字调用父类方法,调用父类方法的语法为:
super.方法名(参数列表)
例如,Cat 类调用父类 Pet 的 eat 方法:
class Pet {
public void eat() {
System.out.println(“宠物吃东西”);
}
}
class Cat extends Pet{
public void eat() {
// 在 eat 方法中调用父类 eat 方法
super.eat();
System.out.println(“小猫饭量很小”);
}
}
class Test {
public static void main(String[] args) {
Cat cat = new Cat();
cat.eat();
}
}
运行结果:
宠物吃东西
小猫饭量很小
5.4 super 与 this 的对比
this
关键字指向当前类对象的引用,它的使用场景为:
-
访问当前类的成员属性和成员方法;
-
访问当前类的构造方法;
-
不能在静态方法中使用。
super
关键字指向父类对象的引用,它的使用场景为:
-
访问父类的成员属性和成员方法;
-
访问父类的构造方法;
-
不能在静态方法中使用。
另外,需要注意的是,在构造方法调用时,super 和 this 关键字不能同时出现。
final
关键字可以作用于类、方法或变量,分别具有不同的含义。在使用时,必须将其放在变量类型或者方法返回之前,建议将其放在访问修饰符和 static
关键字之后,例如:
// 定义一个常量
public static final int MAX_NUM = 50;
6.1 final 作用于类
当 final
关键字用于类上面时,这个类不会被其他类继承:
final class FinalClass {
public String name;
}
// final类不能被继承,编译会报错
public class SubClass extends FinalClass {
}
编译执行,将会报错:
SubClass.java:1: 错误: 无法从最终FinalClass进行继承
public class SubClass extends FinalClass {
^
1 个错误
6.2 final 作用于方法
当父类中方法不希望被重写时,可以将该方法标记为 final
:
class SuperClass {
public final void finalMethod() {
System.out.println(“我是final方法”);
}
}
class SubClass extneds SuperClass {
// 被父类标记为final的方法不允许被继承,编译会报错
@Override
public void finalMethod() {
}
}
编辑执行,将会报错:
SubClass.java:4: 错误: SubClass中的finalMethod()无法覆盖SuperClass中的finalMethod()
public void finalMethod() {
^
被覆盖的方法为final
1 个错误
6.3 final 作用于变量
对于实例变量,可以使用 final 修饰,其修饰的变量在初始化后就不能修改:
class Cat {
public final String name = “小花”;
}
实例化 Cat 类,重新对 name
字段赋值:
Cat cat = new Cat();
cat.name = “小白”;
编译执行,将会报错:
Cat.java:7: 错误: 无法为最终变量name分配值
cat.name = “小白”;
^
1 个错误
通过类的继承,可以大大增加代码的复用性。Java 是单继承的语言,所有类的根类都是 Object
,继承通过 extends
关键字实现。要注意方法重写和方法重载的区别,不要混淆。类方法和 final
方法不能被重写。通过 super
关键字可以访问父类对象成员。final
关键字可以作用于类、方法和变量。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

本次面试答案,以及收集到的大厂必问面试题分享:
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
现在。**
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-QHXrjnlB-1713679054842)]
[外链图片转存中…(img-BhRJMWQv-1713679054843)]
[外链图片转存中…(img-GPgwzYZr-1713679054843)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

本次面试答案,以及收集到的大厂必问面试题分享:
[外链图片转存中…(img-QlcvFiyU-1713679054844)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!