• 面向对象复习(java)


    作用:1. 区分相同名字的类,2. 当类很多时,可以很好管理类,3. 控制访问范围

    如果类用了包,类名就是 包 + 类名
    包的本质就是文件夹



    在本地 cmd 编译

    本地使用包,要用 java -d + 编译后存放的目录 + java 源文件路径 ,-d 会自动生成包(文件夹)



    包规则

    • 包名命名规范中要求全部小写
    • 包名命名规范:公司域名 + 项目名 + 模块名 + 功能名


    import(导包)

    假设 main 类在 A 包,Utils 类在 B 包

    用到别的包的东西,必须要用 包名 + 类名 访问
    因为类名已经变成(类名 + 包名了)

    package A;
    
    public class Main {
        public static void main(String[] args) {
           //静态方法:类名(包名+类名).方法名访问
            B.Util.use();
        }
    }
    
    package B;
    
    public class Util {
        public static void use() {
            System.out.println("调用到了 B 包下的 use");
        }
    
    }
    

    编译的时候记得两个类都要编译


    在同一个包下的话,包名可以省略,如果不在同一个包,想省略,要用 import 导入包

    import B.Util(表示可以省略 B)

    package A;
    
    //导入 表示导入 B 包里面的 Util(可以省略B)
    import B.Util;
    
    public class Main {
        public static void main(String[] args) {
          	//导入 B 包了 所以包名可以省略
            Util.use()
        }
    }
    
    package B;
    
    public class Util {
        public static void use() {
            System.out.println("调用到了 B 包下的 use");
        }
    
    }
    

    举几个例子:

    import java.lang.System;//表示可以 java.lang.System 类可以省略 java.lang
    import java.lang.Math;//表示可以使用 java.lang.Math 可以省略 java.lang
    import static java.lang.Math.sin;// static java.lang.Math.sin 可以省略 java.lang.Math
    import static java.lang.Math.* //表示 static java.lang.Math 下的所有 方法和变量可以省略 java.lang.Math 
    
    //语法糖
    import static java.lang.Math.*;
    public class Main {
        public static void main(String[] args) {
            double a = sin(13.1);
        }
    }
    

    注意

    - java.lang. * 包会系统会自动导入

    • import 语句只能出现在 package 和 class 定义之间
    • import java.util.*:这个 * 表示导入 java.util包下的所有类,这个会浪费元空间




    this

    • this 表示对当前对象的引用
    • this 存储在 实例方法帧栈的局部变量表 第 0 个位置
    • 在构造方法中只能出现在第一行
    • static 方法中 不能用 this ,因为帧栈表中没有
    • 可以用来区分当前类的属性和局部变量


    this 访问实例方法

    this.方法名(参数列表)

    public class Test {
        public static void main(String[] args) {
            new A().m1();
        }
    }
    
    
    class A {
        void m1() {
        	//调用 m2
            this.m2();
        }
    
        void m2() {
            System.out.println("调用到 m2 了");
        }
    }
    


    this 访问构造方法

    访问构造器语法:this(参数列表); 注意只能在构造器中使用

    public class Test {
        public static void main(String[] args) {
            new A();
        }
    }
    
    
    class A {
        int a = 0;
    
        public A() {
        	//调用另一个构造
            this(10);
        }
    
        public A(int a) {
            this.a = a;
            System.out.println("调用到另一个构造了");
        }
    
    
    }
    



    super

    super 代表父类的引用,用于访问父类的属性,方法,构造器


    • 访问父类的属性,但是不能访问父类的 private 属性,语法:super.属性名

    • 访问父类的方法,不能访问父类 private 方法,语法:super.方法名(参数列表)

    • 访问父类构造器,语法:super(参数列表),只能放在构造器第一句,只能出现一句

    super 访问父类构造器

    public class Test {
        public static void main(String[] args) {
            new B(10);
        }
    }
    
    
    class A {
        int a = 10;
    
        public A(int a) {
            System.out.println("调用了父类构造");
            this.a = a;
        }
    }
    
    class B extends A{
        //调用父类构造,在构造本类
        public B(int a) {
            super(a);
        }
    }
    
    

    super访问父类方法

    public class Test {
        public static void main(String[] args) {
            new B().sm();
        }
    }
    
    
    class A {
        int a = 10;
        public A(){};
    
        public void fm() {
            System.out.println("调用到了父类方法");
        }
    }
    
    class B extends A{
        //调用父类构造,在构造本类
        public void sm() {
            super.fm();
        }
    
    }
    

    super 访问父类属性

    public class Test {
        public static void main(String[] args) {
            new B().sm();
        }
    }
    
    
    class A {
        int a = 10;
        public A(){};
    
    }
    
    class B extends A{
    
        int a = 20;
    
        public void sm() {
            //这里输出的是父类的 a
            System.out.println(super.a);
        }
    
    }
    

    如果多个基类(上下类中)都有同名成员,使用 super 访问遵循就近原则,也就是从父类开始一直找到 Object 类



    super 和 this 区别
    一个是从本类开始找到 Object , 一个是从 父类开始找到 Object




    构造方法

    • 一个类可以定义多个不同的构造器,即构造器重载
    • 构造器名要和类名相同
    • 构造器是完成对象的初始化
    • 在创建对象时,系统自动调用该类的无参构造
    • 如果没有构造器就默认调用无参构造,系统会自动生成
    • 如果定义了有参构造,那就不会自动生成无参构造



    访问权限

    在这里插入图片描述




    封装

    没有 static 修饰的类中的变量 叫 实例变量
    没有 static 修饰的类中的变量 叫 实例方法

    封装就是把对象所有 “状态”(属性)”行为“(方法) 统一封装到一个类中,隐藏了对象内部的具体实现细节,向外界提供有限的访问接口,实现对象的保护



    代码实现

    1. 属性私有化
    2. 对外提供public 的 get set 方法

    class A {
        private int a;
        private int b;
    
        public int getA() {
            return a;
        }
    
        public void setA(int a) {
            this.a = a;
        }
    
        public int getB() {
            return b;
        }
    
        public void setB(int b) {
            this.b = b;
        }
    }
    



    继承

    当多个类存在相同 属性,方法,从这些类可以抽象出父类,在父类中定义这些相同的属性和方法,所有子类不需要重写定义这些方法,继承就行

    java 是单继承机制


    细节

    • 除了构造方法和私有的不继承下来,其他都继承下来

    • 子类构造的时候父类一定会先构造,而且默认情况调无参构造,如果没有无参构造,就要用 super 去指定父类哪个构造器,完成初始化工作

    • super() 和 this() 都只能放在构造器第一行,所以,两个方法不能共存在一个构造器

    • 所有类的顶层父类都是 Object 类

    • 用据称必须满足 is-a(泛化关系) ,例如 Cat is Animal


    方法重写(覆盖)

    发生覆盖的条件

    • 具有继承关系
    • 相同的返回值类型,相同的方法名,相同的形参列表
    • 访问权限不能变低,可以变高 (public protected, 默认,private【最低】)
    • 抛出异常不能变多,可以变少
    • 返回值类型可以是父类方法返回值类型的子类
    • 方法覆盖说的是实例方法,和实例变量无关


    子父类同名变量问题

    public class Test {
        public static void main(String[] args) {
            new B().test();
        }
    }
    
    
    class A {
        int a;
    }
    
    class B extends A{
        int a = 10;
    
        public void test() {
            //调用父类 a
            System.out.println(super.a);
            //调用当前类 a
            System.out.println(this.a);
            System.out.println(a);
        }
    }
    


    关于子父类方法的继承问题

    public class Test {
        public static void main(String[] args) {
    
            // test 方法继承到 B 但是返回的还是 父类的 a
            // 因为这个方法的源头就是 a,通过虚函数表传承了
            // 除非是重写了 test 方法
            System.out.println(new B().test());
        }
    }
    
    
    class A {
        int a;
    
        public int test() {
            return a;
        }
    }
    
    class B extends A{
        int a = 10;
    }
    



    多态

    降低耦合度,提高程序过程


    向上转型和向下转型

    向上转型

    父类引用指向子类对象
    编译类型看左边,允许类型看右边

    public class Test {
        public static void main(String[] args) {
            //向上转型
            father f = new Son();
        }
    }
    
    
    class father{
        
    }
    
    class Son extends father {
        
    }
    

    编译类型决定了,能调用哪些东西,也就是子类独有的就用不了了需要向下转型,才能访问

    运行时:先找本类,如果有则调用,如果没有则找父类,再没有就父类的父类


    向下转型

    强制转换成子类类型

    public class Test {
        public static void main(String[] args) {
            //向上转型
            father f = new Son();
            //向下转型
            Son s = (Son) f;
        }
    }
    
    
    class father{
    
    }
    
    class Son extends father {
    
    }
    

    向下转型后,可以调用子类类型中所有的成员



    动态绑定机制

    1. 当调用对象方法时,该方法会和该对象的运行类型绑定
    2. 当调用读写属性时候,没有动态绑定机制,哪里声明,哪里使用

    属性直接访问看编译类型,如果是在函数里面就哪里声明用哪里的无动态绑定机制

    举例

    public class Test {
        public static void main(String[] args) {
            //向上转型
            father f = new Son();
            //返回 10,因为父类声明了,就用父类的
            f.fm(); 
        }
    }
    
    
    class father{
        
        int a = 10;
        
        public int fm() {
            return a;
        }
    
    }
    
    class Son extends father {
        int a = 11;
    }
    



    IDEA 常用快捷键

    • 切换选项卡:alt + 左右方向键
    • 自动是生成变量:.var
    • 删除一行:ctrl + y
    • 查找某个类:敲两次 shift
    • for 快捷键:for+变量名
    • 在一个类中寻找方法 ctrl + F12
    • 单行注释: ctrl + /
    • 多行注释: ctrl + shift + /
    • 多行编辑:按 alt 别松手,鼠标拖动多行,完成多行编辑
    • 查看源码:按 ctrl 别松手,鼠标移动到对应的类名下,出现下划线,点进去
    • 快速向下转型并生成变量名:变量名.castvar



    JVM 体系结构

    在这里插入图片描述


    这只是规范,想要如何设置还是看实现

    在这里插入图片描述

    符号引用:类名, 属性名,方法名
    本地方法栈:有 native 的方法就往这里压


    在这里插入图片描述



    Hotpot 实现

    JDK 6

    在这里插入图片描述
    在这里插入图片描述


    JDK7

    在这里插入图片描述


    JDK8以后
    在这里插入图片描述


    程序运行

    在这里插入图片描述

  • 相关阅读:
    JAVA计算机毕业设计在线直播平台Mybatis+源码+数据库+lw文档+系统+调试部署
    Docker容器的数据卷
    MySQL下载与安装
    BGP高级特性——4字节AS号
    354俄罗斯套娃信封问题
    【Vue十三】-- Vuex详细介绍
    驱动开发:内核CR3切换读写内存
    内核学习——1、list_head
    Clickhouse 学习笔记(6)—— ClickHouse 分片集群
    lightdb21.3-支持语句级hint
  • 原文地址:https://blog.csdn.net/qq_50249256/article/details/139811495