复习篇-继承和接口

(1)如果父类中的方法用private修饰,子类无法继承。(2)子类并不是父类的子集,子类通常比父类的内容多

(3)一个JAVA类只可能直接继承自一个父类,这种限制称为单一继承(single inheritance),多重继承也存在,用接口实现。

(4)子类并不能继承父类的构造方法!!!但是父类的构造方法子类可以调用:使用super()关键字,后面会讲到。

定义:(修饰符)class subclassName extands superclassName{}

子类继承下来的是父类所有可访问的方法,和可访问的数据域。像是所有被 : public 、protected 、default(即默认修饰符,可以不显式使用)所修饰的数据域和方法都可以被继承下来,在子类里都可以直接调用。

Java 单继承,一个类只能直接继承一个父类;所有类直接 / 间接继承 Object。

1.子类和父类在同一包中

同包下,父类以下修饰符成员子类可直接访问:

public:任意访问

protected:同包 + 子类

默认(不写修饰符,包访问权限):同包可访问 private 私有成员无论是否同包,子类都不能直接访问,只能通过父类 public/protected 方法读写。

2.子类和父类不在同一包中

不同包时规则收紧:

public:正常继承、直接访问

protected:可以继承,只能在子类内部访问,不能通过父类对象访问


这句话是说 protected:

// 父类class Person {

protected int age;}

// 子类class Student extends Person {

public void test() {

age = 18; // ✅ 可以,子类内部能访问

}}

class Test {

public static void main(String\[\] args) {

Person p = new Person();

p.age = 18; // ❌ 不行!不能通过父类对象访问

}}

一句话:protected 只能在子类里面用,外面不能用。


默认包权限、private:完全无法继承访问

构造方法不能继承,子类构造默认先调用父类构造

· 创建子类对象时,优先执行父类构造方法,再执行子类构造。

· 隐藏代码:子类构造第一行默认有 super();(调用父类无参构造)。

· 如果父类没有无参构造(只写了有参构造),子类必须手动写 super(实参) 调用父类有参构造,否则编译报错。

class Father {

// 只有有参构造

public Father(String name) {

}}

class Son extends Father {

public Son() {

// 必须写!不写报错!

super("张三");

}}

· 执行顺序:父类静态代码块 → 子类静态代码块 → 父类构造代码块 → 父类构造方法 → 子类构造代码块 → 子类构造方法。

子类定义和父类同名成员变量,称为变量隐藏:

子类范围内直接写变量名,优先使用子类自己的变量。

想访问父类被隐藏变量:super.变量名。

区分:变量隐藏只看名字,和修饰符、类型无关;和方法重写区分开。

class Father{ int num = 10; }class Son extends Father{

int num = 20; // 隐藏父类num

void show(){

System.out.println(num); // 20 子类

System.out.println(super.num); //10 父类

}}

方法重写:子类重写父类同名方法,实现子类特有逻辑,是多态核心。

· 方法名、参数列表、返回值(协变)必须和父类一致;

· 子类方法访问权限不能比父类更严格(父 public,子类不能 private);

· 父类private/final/static方法不能重写;

· 推荐加注解 @Override,编译器校验是否合法重写。

· 重载:同类,同名不同参数;

· 重写:父子类,同名同参数。

super 代表父类对象引用,仅在子类中使用,

· super(参数) 必须放在子类构造方法第一行;

· 作用:主动调用父类有参构造,解决父类无无参构造报错问题;

· 不能和 this() 同时存在(this () 调用本类其他构造,也要求第一行)。

· super.成员变量:访问父类被隐藏的同名变量;

· super.方法名():调用父类被重写的方法;

class Father{

void say(){System.out.println("父类说话");}}class Son extends Father{

@Override

void say(){

super.say(); // 调用父类原方法

System.out.println("子类说话");

}}

final 修饰三种内容,语义:不可修改、不可变更 ;防止被继承、被修改

final 类

final class 类名

特点:不能被继承,没有子类;

场景:工具类,如 String、Math,防止子类篡改内部逻辑。

final 方法

final 返回值 方法名(){}

特点:子类无法重写该方法;

场景:核心通用逻辑,不允许子类覆盖修改。

final 常量

final 修饰基本类型变量:值不能修改;

final 修饰引用类型变量:地址不能改,但对象内部属性可以改;

规范:static final 全局常量,变量名全大写,下划线分隔 MAX_AGE;

局部 final 变量必须声明时赋值。

final int AGE = 18;final Student s = new Student();

s.name = "张三"; // 允许,对象内容可变

s = new Student(); // 报错,引用地址不可变

修饰符

一、访问修饰符(4 个)

作用:控制谁能访问

public:公开,谁都能访问

protected:子类 + 同包能访问

默认(不写):同包能访问

private:私有,只有自己能访问


二、非访问修饰符(常用 5 个)

作用:控制特性、行为

static:静态,属于类,不属于对象

final:最终,不可修改

abstract:抽象,没有方法体

native:本地方法(调用系统底层)

synchronized:线程安全(多线程用)


三、最常用、必须记住的组合

public static final 常量

public static 静态方法

public final 不能继承的类 / 不能重写的方法

private final 私有常量

public abstract 抽象方法

向上转型

父类类型 引用名 = new 子类()

// 父类

class Animal{}

// 子类

class Dog extends Animal{}

// 向上转型

Animal a = new Dog();

形象理解:把小狗Dog向上包装成通用动物Animal,对外只暴露动物的通用能力,隐藏小狗独有的功能。

1.引用是父类类型,只能调用父类中定义过的变量 / 方法;子类独有的方法直接调用会编译报错。

2.如果父类的方法被子类重写,程序运行时,实际执行子类重写后的代码。

向下转型

子类类型 变量名 = (子类类型) 父类引用;

Animal a = new Dog(); // 向上转型

Dog d = (Dog) a; // 向下转型

多态:同一个行为,不同对象不同实现

三个前提:

存在继承 / 实现关系;

方法重写;

父类引用指向子类对象(向上转型)。

运行机制:编译看左边(父类),运行看右边(子类)

· 编译阶段:检查父类是否有该方法;

· 运行阶段:实际执行子类重写后的代码。

同一个动作cry(),动物不同,表现不一样:狗汪汪、猫喵喵、鸡咯咯,这就是多态。

完整多态案例

abstract class Animal{

abstract void cry();}class Dog extends Animal{

@Override void cry(){System.out.println("汪汪");}}class Cat extends Animal{

@Override void cry(){System.out.println("喵喵");}

public class Test{

public static void main(String\[\] args) {

// 多态写法:向上转型

Animal a1 = new Dog();

Animal a2 = new Cat();

a1.cry(); // 汪汪

a2.cry(); // 喵喵

}}

abstract

· 抽象类:abstract class 类名,不能 new 创建对象,只能做父类,配合向上转型使用。

· 抽象方法:abstract 返回值 方法名(); 没有方法体,必须放在抽象类 / 接口中;

· 规则:

包含抽象方法的类必须是抽象类;

普通子类继承抽象类,必须重写所有抽象方法;

子类也是 abstract 抽象类,则可以不重写;

· 抽象类可以有:普通变量、普通方法、构造方法、静态方法。

用abstract修饰,没有方法体,只有方法声明,必须放在抽象类 / 接口中

// 抽象类:动物模板abstract class Animal{

String name;

// 普通构造

public Animal(String name){

this.name = name;

}

// 抽象方法:没有方法体,强制子类重写叫声

abstract void cry();

// 普通方法:所有动物通用

void eat(){

System.out.println(name + "在吃东西");

}}

// 普通子类,必须重写所有抽象方法class Dog extends Animal{

public Dog(String name){

super(name);

}

@Override

void cry() {

System.out.println(name + ":汪汪汪");

}}

接口

关键字interface,代表行为规范、能力标准

· 不能实例化,没有构造方法。

· 成员变量只能是常量(public static final),必须初始化,不可修改。

· JDK7 及以前:全部是抽象方法,实现类必须重写所有抽象方法。

· 解决 Java 单继承局限:一个类只能继承一个父类,但可以实现多个接口拓展能力。

运行

// 定义唱歌能力接口interface Sing{

void singSong();}// 定义跑步能力接口interface Run{

void fastRun();}// 实现多个接口,重写全部抽象方法class Student implements Sing, Run{

@Override

public void singSong() {

System.out.println("学生唱歌");

}

@Override

public void fastRun() {

System.out.println("学生快跑");

}}

// 接口回调(接口多态,向上转型)public class Test{

public static void main(String\[\] args) {

Sing s = new Student(); // 接口引用指向实现类,向上转型

s.singSong();//学生唱歌

}}

import语句

当你要使用不在当前包的其他类时,用import把外部类引入当前文件,不用每次写一长串完整包名。 语法分两种:

精准导入单个类:import 包名.类名;

通配符导入整个包所有类:import 包名.*;

Demo 类(test 包,跨包调用 Student,必须 import)

package test;//表示Demo在test这个包下面,

package com.test;Demo在com这个包下面的test这个包下面

// 导入自定义person包里的Student类

import person.Student;public class Demo {

public static void main(String\[\] args) {

Student s = new Student();

s.study();

}}

  1. java.util.Scanner → 键盘输入(最常用)

作用:接收用户输入数字、字符串

import java.util.Scanner;

  1. java.util.ArrayList → 动态数组(集合)

作用:存一堆数据,比数组好用

import java.util.ArrayList;

  1. java.util.Arrays → 数组工具

作用:数组排序、转字符串

import java.util.Arrays;

  1. java.util.Date → 日期时间

作用:获取当前时间

import java.util.Date;

  1. java.util.Random → 随机数

作用:生成随机数

import java.util.Random;

  1. java.io.* → 文件读写

作用:读取文件、写入文件

import java.io.*;


二、最常用万能写法(导入整个工具包)

如果你不想一个个记,直接写:

import java.util.*;

相关推荐
z落落1 小时前
C# 事件(Event)+自定义带参数事件例子
开发语言·分布式·c#
FlYFlOWERANDLEAF1 小时前
DevExpress Office File API使用记录
开发语言·c#·devoffice
诗词在线1 小时前
求推荐飞花令
大数据·人工智能·python
程序员二叉1 小时前
【JVM】OOM详解+JVM参数+FullGC排查+CPU飙高+死锁+内存泄漏+命令大全
java·开发语言·jvm·面试
云烟成雨TD1 小时前
Spring AI 1.x 系列【47】 MCP Annotations 模块
java·人工智能·spring
yijianace1 小时前
Python线程与多线程完全总结(从入门到理解并发本质)
开发语言·python
不知名的老吴1 小时前
线程的生命周期之线程同步
java·开发语言·jvm
协享科技1 小时前
Spring Boot 与 Go 双服务架构实践:从单体拆分到通信设计
java·人工智能·spring boot·后端·架构·golang·ai编程
J2虾虾2 小时前
C 语言 void 完全用法
c语言·开发语言