JAVA语言中多态和修饰符的关系

打印 上一主题 下一主题

主题 1622|帖子 1622|积分 4866

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x

一、先看一个段子理解多态和修饰符的关系
想象你和小明在玩"角色扮演游戏":
​你是导演(父类),给小明分配了"普通员工"角色(父类方法)
​小明​(子类)说:"我要演得更骚气!"(方法重写)
但导演说:"不可!这个角色被final封印了,你只能按剧本演!"
这就是修饰符对多态的影响——它决定了小明能不能自由发挥演技!
二、访问修饰符:决定"能不能改剧本"   若要搞清晰访问修饰符可点击:                访问修饰符归纳链接访问修饰符归纳链接
1. public(开放派导演)
  1. public class Director {
  2.     public void act() { // 完全开放重写
  3.         System.out.println("标准演技");
  4.     }
  5. }
  6. class XiaoMing extends Director {
  7.     @Override
  8.     public void act() { // 允许魔改
  9.         System.out.println("骚气舞步+激光特效");
  10.     }
  11. }
复制代码
结果:小明可以随意发挥(完美多态)换句话说:任何类都能调用和重写,多态的"完全体形态"
​经典场景:接口方法默认public,实现类必须重写(如Runnable.run())
2. protected(有限开放导演)
  1. protected void act() {
  2.     // 仅允许自家剧组(同包或子类)修改
  3. }
复制代码
潜规则:假如小明在别的影视公司(不同包),须要走后门(继续)才能改剧本,换句话说:
跨包继续时,子类必须通过继续关系才能重写
​实战技巧:得当框架设计中的模板方法模式(父类定义骨架,子类添补细节)

  • default默认(包级导演)
    void act() {   // 只允许同剧组(同包)修改 }
    致命伤:小明跳槽到其他公司(不同包)时,会收到"改剧本权限不足"警告,换句话说:
跨包开发时,"看似继续实则无法重写"的坑点
​规避方案:跨包协作时显式使用public/protected
4. private(霸道总裁导演)
private void act() {      // 完全私有,禁止修改 }
现实案例:就像老板的加密文件,实习生连看的机会都没有,更别说修改(无法重写)
本质:子类同名方法≠重写,是平行宇宙的新方法
反模式案例:试图用子类private方法覆盖父类public方法导致多态失效
三、特殊修饰符:多态的"封印术"
1. final(如来佛封印)
`public final void act() { ... } // 方法封印
public final class Director { ... } // 类级封印`
三连暴击:
封印方法:子类只能照本宣科(无法重写)
封印变量:像被焊死的螺丝(常量)
封印类:直接断绝子嗣(无法继续)
​内存原理:final变量在编译期优化(常量池),方法内联优化
设计哲学:JDK中的String类被final修饰,保证不可变性安全
2. static(机器人演员)
public static void act() { ... }
反多态三定律:
属于类而不是实例(像没有灵魂的AI)
编译时绑定(导演提前录好的磁带)
同名不算重写,是隐藏(替人演员冒充本尊)
​字节码原形:静态方法在invokestatic指令中绑定,无多态性
​常见误区:误以为静态方法可以重写,现实是类级别
Director.act(); // 永久调用父类 XiaoMing.act(); // 这是新的静态方法!
3. abstract(逼迫创新导演)
public abstract void act(); // 必须重写
创作自由:
父类只给剧本大纲(抽象方法) 子类必须自己写分镜(逼迫实现)
模板方法模式:Hibernate的SessionImpl类,抽象方法由不同数据库实现
​设计规范:抽象类至少有一个抽象方法,逼迫子类创新
四、修饰符组合技(开发者必看)

  • 最骚操纵:
    public abstract class Animal {  public abstract void eat(); // 必须重写  public final void breathe() { // 禁止修改      System.out.println("氧气是人类的朋侪");  } }
    设计哲学:
呼吸方法final:生命不可儿戏
进食方法abstract:允许自由发挥
2. 殒命组合:
private final static String DNA = "ATCG";
四重封印:
私有访问 + 不可修改 + 类级别存在 + 常量
五、避坑
​final偷袭:重写final方法时,编译器会露出姨母笑(报错)
​静态伪装:以为重写static方法,现实是创建新方法
​跨包悲剧:用默认修饰符写的方法,在其他包无法多态
​private假动作:子类定义同名方法≠重写,是平行世界的新方法
六、多态机制:
一.影帝的千面人生
​1. 动态绑定(幕后特效)​
Animal animal = new Cat(); animal.eat(); // JVM通过虚方法表查找Cat.eat()
​JVM原理:虚方法表(vtable)实现运行时查找
​性能优化:HotSpot假造机的内联缓存(Inline Cache)
​2. 转型操纵(换装魔法)​
// 向上转型(自动)
Actor actor = new StuntDouble();
// 向下转型(需显式) if(actor instanceof StuntDouble) {     StuntDouble sd = (StuntDouble)actor;     sd.dangerousAction(); }
​ClassCastException:Spring框架的Bean转型异常处理
​范例检查:Apache Commons的ClassUtils工具类封装
​3. 构造器陷阱(时间悖论)​
`class Father {
public Father() {
init(); // 伤害操纵!
}
public void init() { /.../ }
}
class Son extends Father {
private String data;
@Override
public void init() {
System.out.println(data.length()); // NPE!
}
}​对象初始化顺序:父类构造器→子类成员变量初始化→子类构造器 ​安全规范:《Effective Java》条款19:禁止在构造器中调用可重写方法 二、实战:剧组生存指南 ​1. 防御式编程public final class SafeActor {
// 防止恶意子化
private final Object lock = new Object();
  1. // 敏感方法封闭
  2. public final void coreLogic() { /*...*/ }
复制代码
}​2. 框架设计 // Spring风格的抽象模板public abstract class JdbcTemplate {
public final void execute() {
getConnection();
doStatement(); // 抽象方法
releaseConnection();
}
protected abstract void doStatement();
}​3. 性能优化 ​​​​ // 用final促进JIT编译优化public class Vector3D {
private final double x, y, z; // 根本范例final提拔性能
// ...
}​4. 安全审计 // FindBugs规则:检查final方法被不测重写if (!method.isFinal() && hasOverrideInSubclass()) {
reportSecurityRisk();
}三、全维度对照表 修饰符        多态影响        典型应用场景        JVM级特性public        完全开放多态        接口方法实现        虚方法表绑定
protected        受控继续情况多态        模板方法模式        跨包访问检查
private        禁止多态(方法隐藏)        内部工具方法        编译期静态绑定
final        封印多态(禁止重写/继续)        工具类/常量定义        方法内联优化
static        破坏多态(类级别绑定)        工具方法/单例模式        invokestatic指令
abstract        逼迫多态(必须重写)        框架扩展点设计        抽象方法报错校验`
四、开发者自查清单
是否全部public方法都考虑过被重写的风险?
final修饰的核心方法是否做了文档说明?
跨包继续时protected方法是否考虑访问控制?
静态方法是否被误用导致多态失效?
构造器中是否存在可重写方法调用?
向下转型是否都有instanceof安全检查?
抽象类的抽象方法是否稳定无需修改?
假如把这些概念比作剧组规则:
​public是主角的自由发挥权 ​protected是副角的限定戏份 ​final是剧本的不可修改条款 ​abstract是导演留下的即兴发挥空间 ​多态就是演员的千人千面表演本事
理解这些规则,你就能在Java世界里既遵守规范,又演绎出精彩代码
​开放原则:须要多态的方法用public/protected
​安全锁:核默算法用final保护
​静态警示:工具类方法用static,但注意失去多态特性
​抽象契约:定义接口时多用abstract逼迫规范
​权限最小化:像管理后宫一样管理访问权限
举个栗子:咖啡店多态系统
`public abstract class Coffee {
public final void prepare() { // 固定流程
boilWater();
brew();
pourInCup();
addCondiments();
}
  1. protected abstract void brew(); // 必须实现
  2. protected abstract void addCondiments();
  3. private void boilWater() { ... } // 底层细节不开放
  4. public static void cleanMachine() { ... } // 静态方法
复制代码
}
class Latte extends Coffee {
protected void brew() { ... } // 必须实现
protected void addCondiments() { ... }
  1. public static void cleanMachine() {
  2.     // 这是新的静态方法!
  3. }
复制代码
}
`
设计精妙:
prepare()用final保护制作流程
抽象方法逼迫子类创新
静态方法实现工具功能
私有方法封装实现细节
记住:​修饰符是代码世界的交通规则,多态是老司机的漂移技巧。合理使用能让你的代码既有规律性,又能玩出骚操纵!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

涛声依旧在

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表