当前位置: 首页 > news >正文

Java中的继承:从入门到精通

一、什么是继承?

继承是面向对象编程的三大特性之一(封装、继承、多态)。简单来说,继承就是让一个类拥有另一个类的属性和方法,就像孩子继承父母的财产一样。

// 父类(基类) public class Animal { String name; public void eat() { System.out.println(name + "正在吃东西"); } } // 子类(派生类) public class Dog extends Animal { public void bark() { System.out.println(name + "汪汪叫"); } } // 使用 public class Test { public static void main(String[] args) { Dog dog = new Dog(); dog.name = "旺财"; // 继承了父类的属性 dog.eat(); // 继承了父类的方法 dog.bark(); // 自己的方法 } }

二、为什么要使用继承?

1.代码复用

避免重复编写相同的代码,提高开发效率。

没有继承的糟糕代码:

public class Dog { String name; int age; public void eat() { System.out.println("吃东西"); } public void sleep() { System.out.println("睡觉"); } } public class Cat { String name; int age; public void eat() { System.out.println("吃东西"); } public void sleep() { System.out.println("睡觉"); } } // 每个动物都要重复写name、age、eat()、sleep()

使用继承优化后:

public class Animal { String name; int age; public void eat() { System.out.println("吃东西"); } public void sleep() { System.out.println("睡觉"); } } public class Dog extends Animal { // 自动拥有name、age、eat()、sleep() public void bark() { System.out.println("汪汪"); } } public class Cat extends Animal { // 自动拥有name、age、eat()、sleep() public void meow() { System.out.println("喵喵"); } }

2.建立类之间的层次关系

继承能体现现实世界中的“is-a”关系(狗是一种动物,猫也是一种动物)。


三、继承的关键语法

1.extends关键字

Java中使用extends来实现继承,一个类只能继承一个父类(单继承),但是支持多层继承。

public class 子类 extends 父类 { // 子类特有的属性和方法 }

2.方法重写(Override)

子类可以重写父类的方法,实现自己特有的行为。

public class Animal { public void sound() { System.out.println("动物发出声音"); } } public class Dog extends Animal { @Override // 注解,表示重写父类方法(可选但推荐) public void sound() { System.out.println("汪汪汪"); } } public class Cat extends Animal { @Override public void sound() { System.out.println("喵喵喵"); } }

3.super关键字

super用于访问父类的成员(属性、方法、构造方法)。

public class Animal { String name; public Animal(String name) { this.name = name; } public void eat() { System.out.println(name + "在吃东西"); } } public class Dog extends Animal { String breed; // 品种 public Dog(String name, String breed) { super(name); // 调用父类构造方法,必须是第一条语句 this.breed = breed; } public void eat() { super.eat(); // 调用父类的eat方法 System.out.println(name + "在啃骨头"); } public void showInfo() { System.out.println("名字:" + super.name); // 访问父类属性 System.out.println("品种:" + this.breed); } }

4.this()方法如何用

this()是Java中的一个特殊语法,用于在同一个类的构造方法中调用另一个构造方法。它和super()是“兄弟”,一个调用本类构造方法,一个调用父类构造方法。

public class Student { private String name; private int age; private String grade; // 构造方法1:三个参数 public Student(String name, int age, String grade) { this.name = name; this.age = age; this.grade = grade; System.out.println("调用三个参数的构造方法"); } // 构造方法2:两个参数 public Student(String name, int age) { this(name, age, "未分班"); // 调用构造方法1 System.out.println("调用两个参数的构造方法"); } // 构造方法3:一个参数 public Student(String name) { this(name, 18); // 调用构造方法2 System.out.println("调用一个参数的构造方法"); } public static void main(String[] args) { Student s1 = new Student("张三"); // 输出: // 调用三个参数的构造方法 // 调用两个参数的构造方法 // 调用一个参数的构造方法 } }

不能循环调用

public class Example { public Example() { this(1); // 调用有参构造 } public Example(int x) { this(); // 错误!循环调用,编译报错 } }

this() 和 super() 不能共存,因为两者都必须是第一条语句,所以不能同时出现。

public class Parent { public Parent(String msg) { System.out.println("Parent: " + msg); } } public class Child extends Parent { public Child() { // 错误!不能同时使用 // this("张三"); // super("默认"); // 正确做法:选择其中一个 super("默认"); // 或者使用 this() } public Child(String name) { this(); // 调用本类无参构造 // super() 会在 this() 调用的构造方法中执行 } }

四、继承中的访问权限

访问修饰符对继承的影响:

package com.parent; public class Parent { private String privateField = "私有"; String defaultField = "默认"; protected String protectedField = "受保护"; public String publicField = "公共"; private void privateMethod() {} void defaultMethod() {} protected void protectedMethod() {} public void publicMethod() {} } package com.child; import com.parent.Parent; public class Child extends Parent { public void test() { // privateField 不可访问 // defaultField 不可访问(不同包) protectedField = "可以访问"; // ✓ publicField = "可以访问"; // ✓ // privateMethod() 不可访问 // defaultMethod() 不可访问 protectedMethod(); // ✓ publicMethod(); // ✓ } }

五、继承的注意事项

1.构造方法的调用顺序

先调用父类构造方法,再调用子类构造方法。

public class Parent { public Parent() { System.out.println("父类构造方法"); } } public class Child extends Parent { public Child() { // 隐藏了super(),自动调用父类无参构造 System.out.println("子类构造方法"); } } // 输出: // 父类构造方法 // 子类构造方法

2.final关键字

  • final修饰的类不能被继承

  • final修饰的方法不能被重写

  • final修饰的变量是常量

final class FinalClass { // 这个类不能被继承 } public class Parent { public final void finalMethod() { // 这个方法不能被重写 } } public class Child extends Parent { // 编译错误!不能重写final方法 // public void finalMethod() {} }

3.Object类

Java中所有类都直接或间接继承自Object类,它提供了通用方法。

public class MyClass { // 隐式继承了Object类 // 拥有toString(), equals(), hashCode()等方法 } // 重写toString方法示例 public class Person { String name; int age; @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } }

六、实战案例:游戏角色系统

// 基础角色类 public class GameCharacter { protected String name; protected int hp; protected int level; public GameCharacter(String name, int hp, int level) { this.name = name; this.hp = hp; this.level = level; } public void attack() { System.out.println(name + "发动了攻击"); } public void takeDamage(int damage) { hp -= damage; System.out.println(name + "受到" + damage + "点伤害,剩余生命:" + hp); } public void showInfo() { System.out.printf("角色:%s,等级:%d,生命:%d%n", name, level, hp); } } // 战士类 public class Warrior extends GameCharacter { private int rage; // 怒气值 public Warrior(String name, int hp, int level) { super(name, hp, level); this.rage = 0; } @Override public void attack() { rage += 10; System.out.println(name + "挥舞大剑攻击!怒气:" + rage); } public void berserkerMode() { if (rage >= 50) { System.out.println(name + "进入狂暴模式!攻击力大幅提升!"); rage -= 50; } else { System.out.println("怒气不足,需要" + (50 - rage) + "点怒气"); } } } // 法师类 public class Mage extends GameCharacter { private int mana; // 魔法值 public Mage(String name, int hp, int level) { super(name, hp, level); this.mana = 100; } @Override public void attack() { if (mana >= 10) { mana -= 10; System.out.println(name + "释放火球术!剩余魔法:" + mana); } else { System.out.println(name + "魔法不足,只能普通攻击"); super.attack(); } } public void recoverMana() { mana += 20; System.out.println(name + "恢复魔法值:" + mana); } } // 使用示例 public class GameDemo { public static void main(String[] args) { Warrior warrior = new Warrior("战士小明", 1000, 10); Mage mage = new Mage("法师小红", 600, 10); warrior.showInfo(); mage.showInfo(); warrior.attack(); mage.attack(); warrior.berserkerMode(); mage.recoverMana(); } }
http://www.jsqmd.com/news/536882/

相关文章:

  • LD8035显示驱动芯片技术文档为何无法生成?
  • MedGemma-X惊艳效果:上传一张胸片,获得多维度结构化诊断分析
  • PyTorch 2.8镜像应用场景:广告公司定制化AI创意生成私有平台案例
  • ChatTTS与OpenVoice本地部署实战:从语音合成到高效推理的完整指南
  • Llama-3.2V-11B-cot实战教程:上传→提问→展开推演→导出结论四步闭环
  • ABAQUS有限元模型:基于CEL算法的斜桩锤击入土模拟
  • 现代C++ | 基础革命特性
  • 吃透 Android 布局资源:从 Chapter2 实战项目看懂四大核心布局
  • 国家金融监督管理总局地市级分支局计算机岗之日常运维:从基础到进阶的全面解析
  • 无源晶振如何用
  • PCB画板时的层数设置
  • Axios + Vue 错误处理规范:中后台项目实战,统一捕获系统 / 业务 / 接口异常|API 与异步请求规范篇
  • 2026 本科论文 AI 工具榜单: 9 款神器,搞定从选题到答辩全流程
  • 边缘AI网关搭建:YOLO12-N在智能交通摄像头中的低延迟部署方案
  • Qwen3.5-4B-Claude-Opus应用场景:在线教育平台嵌入式推理助手
  • 未来运维工程师的核心竞争力,可能跟你想的不太一样
  • OpenClaw自动化办公:用GLM-4.7-Flash实现邮件自动整理与回复
  • pnpm 使用教程
  • 利用DeepSeek接口构建高并发智能客服系统的架构设计与性能优化
  • C语言实现多态相关话题
  • 答辩逆袭指南:Paperxie AI PPT 如何让论文答辩从 “手忙脚乱” 变 “从容出彩”
  • RTX4090D显存优化:OpenClaw长文本处理对接Qwen3-32B实测
  • weixin258基于微信小程序的课堂点名系统springboot(文档+源码)_kaic
  • 【大模型学习】常见AI工作流框架组合
  • 用ABAQUS玩转液压油缸模拟:基于CEL算法的加载模型
  • H3CNE--17.DHCP和DHCP中继代理
  • 告别Fiddler和Charles!用Jmeter代理抓取手机APP接口请求的保姆级教程(含证书安装避坑)
  • DanKoe 视频笔记:个人商业模型:第三部分:如何将知识转化为价值
  • Voron 2.4:开源3D打印机-树莓派3B+和蜘蛛3.0主板(一) 树莓派程序烧录Mainsail
  • CosyVoice 2 目标音色替换技术解析:从原理到小白友好实现