【JAVA】JAVA核心基础--面向对象

1.类和对象

2.1概念:

  1. 面向对象:虚拟世界模拟现实生活,必须要保证模拟一致

  2. 面向过程:按照顺序(步骤)逐步完成

  3. 类:
    对同一类事物的抽象的描述,

    也就是:不仅具体的
    例:电脑类、水杯类、人类、动物类、鱼类……

  4. 对象:
    万物皆对象,(具体的实例)
    例:我的电脑、某某的水杯

  5. 类与对象之间的关系
    抽象与具体的关系

  6. 描述对象的特征,称为属性
    例:颜色、尺寸、品牌、价格……

  7. 对象实现的功能,或者对象所做的事情,称为方法
    例:打电话、拍照……

  8. 张三对象:

    属性:姓名、性别、身高、体重、年龄、电话号码、家庭住址……

    方法:学习、说话、吃饭、睡觉……

  9. 李四对象:

    属性:名字、年龄、性别、身高、体重、身份证号………

    方法:玩游戏、跑步、打篮球、学习…….

  10. 将多个对象找到相同的属性和方法组合在一起形成一个类

    • 学生类

      属性:姓名、年龄、性别、身高、体重

      方法:学习

2.编写面向对象的代码(重点)

第一步:编写类
  • 编写类的语法格式:

    [修饰符] class 类名{

    }

    注意事项:

    1. 在面向对象中,类名建议:编写单词,每个首字母大写
第二步:编写属性也叫做编写成员变量或者叫做字段
  • 注意事项:

    1. 属性编写在类中;

    2. 编写属性语法格式:
      [修饰符] 数据类型 属性名 [= 值 ];

    3. 属性名也就是标识符,建议:编写单词,并且采用驼峰命名

    4. 当创建对象后,如果属性没有赋值则是有默认值的,数据类型不同默认值不同,具体如下:

      • 整数类型默认值为0

      • 浮点类型默认值为0.0

      • 字符类型默认值为\u0000

      • 布尔类型默认值为false

      • 所有引用数据类型默认值为null

第三步:编写方法
  1. 方法的语法格式:

    [修饰符] 返回值类型 方法名称 ([参数列表]){

    方法体

    }

  2. 在面向对象中,方法的修饰符==暂时==编写为public

  3. 编写测试Test类

  • 其实就是包含main方法的类
  • test 测试
  1. 创建对象
  • 语法格式:类名 引用名 = new 类名();
  • 注意:一个类可以创建任意多个对象
  1. 访问对象中的属性和方法

    5.1 访问对象属性中的属性

    • 获取属性的值
      引用名.属性名
    • 对属性赋值
      引用名.属性名 = 值;

    5.2访问对象中的方法

    • 引用名.方法名称([参数列表]);
    • 注意:在面向对象中,方法没有编写static,因此不能使用类名. 否则就出现编译错误

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UueqSzJS-1669733051474)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20210608192642455.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YqdUQwzC-1669733051475)(C:\Users\86136\AppData\Roaming\Typora\typora-user-images\image-20210608192647588.png)]

6.局部变量与成员变量区别(重点、难点)

6.1 声明位置不同

  • 局部变量:在方法中声明的变量

  • 成员变量:在方法外面声明的变量或者在类中声明的变量

6.2 作用范围不同

  • 局部变量:在当前声明距离最近的大括号内使用,作用范围相对更小

  • 成员变量:在本类(当前类)中可以直接使用,称为全局变量,作用范围相对更大

6.3 初始值不同

  • 成员变量:0当创建对象后,如果没有对象成员变量赋值,则成员变量是有默认值的,数据类型不同默认值不同

  • 局部变量:没有默认值,也就是说:局部变量必须要先声明,然后再赋值,最后才可以使用

6.4 在同一个类中,局部变量的名字与成员变量的名字相同,不报错,但是局部变量优先,也就是:就近的优先,如果非要使用成员变量,则必须使用this.

  • 在Java中,this代表当前这个对象,也就是:当前谁调用这个方法则这个对象就是谁

7.构造方法以及构造方法的重载:

构造方法:
1.构造方法作用(重点)
完成对属性赋值
2.构造方法是一个特殊的方法,主要有以下两点:
构造方法的名字必须与类名一致
构造方法必须没有返回值类型,也就是:都不需要编写void
3.构造方法的语法格式
public 类名([参数列表]){

}
4.构造方法快捷键(重点)

第一种方式:光标放在类中,按Alt + Insert键,选择第一项Constructor构造器、构造方法、构造函数,按回车键,按两次Tab键,再按回车,则生成无参构造方法

注意:大多数情况下,无参构造方法体中不编写任何内容**,**也就是:执行无参构造方法时,属性都是默认值

第二种方式:光标放在类中,按Alt + Insert键,选择第一项Constructor回车,鼠标左键点击第一个要赋值的属性,然后再按Ctrl +鼠标左键点击其他要赋值的属性,最后按回车键,则生成带参构造方法,完成对部分属性赋值
第三种方式:光标放在类中,按Alt + Insert键,选择第一项Constructor回车,按Ctrl + A全选,再按回车键,则生成带参构造方法,完成对所有属性赋值

5.构造方法如何执行?(重点)
当创建对象时,会自动找相匹配的构造方法执行
1.当编写new之后,敲一个空格,然后编写部分类名的字母,则就会出现提示框,可以按方向键上键或者下键进行选择要执行的构造方法,

3.注意事项:
当没有在IDEA中设置,如果编写new之后,敲一个空格,然后再编写部分类名时,则没有选择要执行哪个构造方法,则查看是否在类中编写多个构造方法,如果编写构造方法,则需要进行如下设置
File—>Settings—>Editor—>General—>Code Completion—>右侧将参数基本设置中的第一项和担心勾上—>
6.构造方法注意事项:
6.1当在一个类中没有编写构造方法,则系统会提供一个默认的无参的构造方法,也称为隐式构造方法
也就是说:当一个类中没有编写构造方法,则有一个无参构造方法
6.2当在一个类中编写构造方法,则系统不会提供无参的构造方法,也称为显式构造方法
也就是说:当一个类中编写几个构造方法,则就共计有几个构造方法
6.3建议:当编写构造方法时,先编写无参构造方法,然后再编写需要的带参构造方法,否则在后面使用无参构造方法时,没有无参构造方法,则就会出现编译错误
7.构造方法重载
7.1什么是构造方法重载?
在同一个类中,构造方法的名字必须相同,参数列表必须不同(个数不同、类型不同、顺序不同),至少编写2个构造方法
7.2当构造方法构成重载后,如何确定执行的是哪个构造方法?
在创建对象时,会根据实参的值自动找相匹配的构造方法执行,否则出现编译错误
7.3构造方法重载好处
在使用时,相对更灵活

  1. 变量按数据类型分为

    • 基本数据类型:在**内存中存放的是真正的值**

    • 引用数据类型:在内存中存放的是地址(引用)
      类(class)

      • 系统提供的类,比如:string、……
      • 用户自定义的类,比如:Car、Student、Computer……
      1. 对引用数据类型赋值方式有两种
        • 第一种:将对象的内存地址赋给左侧的引用名称
          c = new Car();
        • 第二种:将null值赋给左侧的引用名称
          c = null;
  2. 空指针异常

    1. 属于运行错误 java.lang.NullPointerException
  3. 出现空指针异常原因:

  • 当前引用名中存放的是null,也就是没有存放某个对象的地址,因此就没有指向某个对象,则就不能访问对象中的属性或方法,如果非要访问则就出现空指针异常

3.解决办法:

  • 在访问对象中的属性或方法之前,必须保证引用名中存放的是地址(引用)
  1. 参数传递

    1. 基本数据类型作为参数传递
      基本数据类型在内存中存放的是真正的值,
      • 因此:实参传递给形参的是真正的值,也就是拷贝一份,当另一个方法局部变量的值更改,对原来方法中局部变量的值没有任何影响
  2. 引用数据类型作为参数传递

    引用数据类型在内存中存放的是地址(引用)

    • 实参传递给形参的是地址(引用),也就是:实参与形参存同一个地址,指向同一个对象,当另一个引用名中的属性值发生改变,对原来引用名中的属性值有影响;

​ 3. 对象中的属性可以是用户自定义数据类型

  1. this关键字

    • 在java中,this代表当前这个对象,也就是:当前谁调用这个方法,则这个对象就是谁
    • 在java中,this关键字可以访问本类(当前类)中的实例变量,实例方法以及本类中的其他构造方法
  2. this关键字访问本类中的实例变量(重点)

    1. this关键字可以访问本类中的实际变量:
    • 当属性(成员变量或者字段)前面没有编写static关键字称为实例(对象)变量
    • 实例变量什么时候存在?
      当创建对象时,会在堆内存的对象开辟空间存储
    • 当没有局部变量与实例变量同名,则可以在本类中直接使用实际变量,默认在实际变量前面添加this.
    • 在同一个类中,局部变量与实例变量可以同名,不报错,但是就最近的优先也就是局部变量优先,
      如果非要实例变量,则必须编写为this.
    1. this关键字访问本类中的实例方法
this关键字访问本类中的实例方法
*      2.1当方法没有使用static关键字修饰,称为实例方法,也就是对象的方法
*      2.2当访问本类中的实例方法时,默认前面编写this.
*         比如:print();  其实等价于this.print();

​ 3. this关键字还可以访问本类中的其他构造方法

3.this关键字还可以本类中的其他构造方法
  3.1访问本类中的构造方法,使用this关键字
  3.2如果this后面小括号中没有内容,则执行本类无参构造方法,否则执行本类相匹配的带参构造方法
  3.3注意事项:
     当使用this关键字访问本类构造方法时,只能编写在构造方法中,并且是第一条语句
     this关键字访问构造方法时,只能访问本类中的其他构造方法,也就是:构造方法不能自己调用,死循环,没有意义

3.封装

  • 1.在java,面向对象有三大特征:封装、继承、多态

  • –有时也会问面向对象四大特征:封装、继承、多态、抽象,其实抽象是面向对象程序设计的方法–

  • 2.什么是封装?

  • 在现实生活中,封装也就是:包装或者包裹,比如:快递、外卖…

  • 在java中,封装也就是:隐藏类的内部信息,不允许外部程序直接访问,而是通过方法完成

  • 3.封装的操作步骤:(重点)

  • 第一步:将==实例变量前面编写private,==也就是:该实例变量只能在本类(当前类)中使用

  • 第二步:编写对应实例变量的方法(取值方法和赋值方法)

    1. 第1种情况:光标放在类中,按Alt + Insert键,选择第二项Getter,按回车键,则生成取值方法

    其中Getter表示取值方法

    大多数情况下,一个实例变量对应一个取值方法get

    1. 第2种情况:光标放在类中,按Alt + Insert键,选择第三项Setter,按回车键,生成赋值方法

    其中Setter表示赋值方法

    大多数情况下,一个实例变量对应一个赋值方法set

    1. 第3种情况:光标放在类中,按Alt + Insert键,选择第四项Getter and Setter,按回车键,则生成取值和赋值方法

    大多数情况下,一个实例变量对应一个取值方法和一个赋值方法

  • 第三步:根据情况,在赋值方法set中编写判断语句

  • 比如:年龄在1—150岁范围内为合法,否则实例变量年龄的值18

  • 性别只能是男或女为合法,否则实例变量性别的值为女

    4.封装好处:值相对更安全(也就是:值更合法或者值有效、有意义)

  1. 优化封装:
    1. 当set方法设置为Builder时,则该方法生成带参带返回值类型的

    2. 当set方法返回当前对象时,在使用时就可以进行连缀操作

      返回的是当前对象可以写为:
      引用名.实例变量().实例变量().实例变量();

4.继承(重点):

  1. 发现并列子类中,有相同的属性和相同的方法,则就可以使用继承完成;

    第一步:将多个类中相同的(公共的)属性和方法存放在单独的一个类中,称为父类

    第二步:编写子类继承父类

    第三步:在子类中编写独有(特有的)属性和方法

  2. 继承的好处

    • 减少代码的冗余性(重复性),提高代码的复用性
  3. 编写继承代码(重点)

    1. 第一步:编写父类

      • 语法格式:
        [修饰符] class 父类类名{

        公共的属性和方法

        }

    2. 第二步:编写子类

      • 语法格式:
        [修饰符] class 子类类名 extends 父类类名{

        独有的属性和方法

        }

    3. 注意事项:

      • 在Java中,当一个类没有使用 extends 指定继承哪个父类时,则系统默认继承object类
        当继承object类时,extends object 可有可无
      • 在Java中,object是所有类的父类
  4. 重写override(重点、难点)

    1. 什么时候进行方法的重写?
      当分类中的方法不能满足子类的需求,则需要在子类中重写父类中的方法
      因此重写也叫覆盖

    2. 重写规则
      Ø 在子类中重写父类的方法

      Ø 不能缩小访问权限

      Ø 返回值类型必须一致 或者 父类方法返回值类型的子类类型

      Ø 方法名称必须一致

      Ø 参数列表必须一致

    3. 重写快捷键(重点)

      光标放在子类中,按 ctrl + o 选择父类中要重写的方法,按回车键

    4. 重写注意事项
      当子类中重写父类的方法后,再调用方法,则调用子类重写以后的方法,也就是说:父类中的方法使用不到,但是必须不能删除

  5. 继承注意事项

    1. 父类也叫超类,基类superclass ,子类也叫做派生类 subclass

    2. 子类继承父类时,不能继承父类的构造方法

    3. 继承满足条件:
      例:猫是动物、狗是动物

    4. 继承有两大特性:

      • 单根性
        再Java中一个类只能继承一个直接的父类,类是单继承

      • 类具有传递性

        class A{

        ​    有2个属性和2个方法

        }

        class B extends A{

        独有属性5个,独有方法2}

        class C extends B{


         }
  1. this关键字与super关键字的区别

    • 1.this关键字代表

      ​ Ø 代表当前这个对象,也就是说:当前谁调用这个方法,则这个对象就是谁

      ​ Ø 在当前类中使用,可以访问当前类中的内容,也可以访问父类中的

      2. this关键字可以访问

      ​ Ø 可以访问本类(当前类)中的实例变量、实例方法,以及本类中的其他构造方法

      ​ Ø 还可以访问父类中的实例变量和父类中的实例方法

      3. this关键字访问实例变量、实例方法时,查找顺序在

      ​ Ø 先在当前类中找,如果没有找到则再去父类中找该实例变量或实例方法

    • 1. super关键字代表

      super代表父类也就是超类

      只能在子类中使用,访问父类中的内容

      2. super关键字可以访问

      Ø 可以访问父类中的实例变量和父类中的实例方法

      Ø 还可以访问父类中的构造方法

      当子类构造方法中没有使用super关键字指定调用父类哪个构造方法,则系统默认调用父类无参构造方法

    • super关键字访问父类中的实际变量或实例变量,查找顺序

      1. 直接去父类中找该实际变量或实例方法
      2. 因此使用super. 访问父类中的实例变量或实例方法,查找速度相对更快或者执行效率更高,因此建议使用super. 访问父类中实际变量或实例方法
    • super关键字注意事项

      1. 不能使用super. 访问子类独有的实际变量或实例变量
  2. 当创建子类对象时,父类做了什么
    先执行父类构造方法,然后再执行子类相匹配的构造方法

5.Static 关键字

表示静态的

可以修饰属性、方法、代码块、内部类以及实现静态导入

1.static关键字修饰属性
      1.1在类中声明的变量,称为成员变量,也叫做属性或者叫做字段f
         如果属性前面没有编写static关键字称为实例变量,也叫做对象的变量
         如果属性前面编写static关键字称为静态变量,也叫做类的变量
      1.2静态变量特点:
          1.2.1当类加载到内存时,就给静态变量分配空间,一直到程序结束
          1.2.2静态变量:在JDK8.0之前在方法区中存储
                       在JDk8.0之后在堆中存储
          1.2.3静态变量与类同生死,也就是类在静态变量就存在,因此静态变量也叫做类的变量
          1.2.4静态变量访问方式:
             使用类名.静态变量名
              也可以使用引用名.静态变量名
              当引用名中存放的是null,依然可以访问静态变量,不会出现空指针异常,因为:静态变量不属于某一个对象,一直到程序结束
          1.2.5静态变量不属于某一个对象,是当前类所有对象都可以共享
          1.2.6类优先于对象,也就是说:类的生命周期比较长
      1.3什么时候将属性编写为static修饰?
          当多个对象中的某个属性的值都一样时,建议:编写为静态变量,原因:节省空间,并且所有对象都可以共享
3.static关键字修饰代码块
*      3.1使用static关键字修饰代码块,称为静态代码块
*      3.2静态代码块语法格式
*          static{
*
*          }
*      3.3静态代码块作用:完成对静态变量赋值
*      3.4静态代码块怎么执行?
*          当类加载到内存时,执行静态代码块,并且只执行一次
4.static关键字修饰内部类
*      4.1什么是内部类
*          在一个类中,再编写一个类,里面的这个类,称为内部类,也叫做内置类或者嵌套类
*      4.2一般什么时候编写内部类?
*          内部类是对外部类提供服务的,如果内部类还想对其他外部类提供服务,则不建议编写为内部类
*      4.3当在内部类前面编写static关键字,称为静态 内部类

  1. static 关键字可以实现静态导入

2.5访问权限

  1. 类的访问权限

    ​ 公共类和非公共类

    • 当一个类前面你编写 public 修饰符,当类称为公共类,也就是:该类可以在任意包中都可以使用
    • 当一个类前面没有编写public 修饰符,该类称为非公共类,也就是:该类只能在当前类中使用
  2. 成员的访问权限

    访问权限在当前类中在当前包中不同包的子类任意包任意类
    private私有的可以使用不可以使用不可以使用不可以使用
    默认的可以使用可以使用不可以使用不可以使用
    protected受保护可以使用可以使用可以使用不可以使用
    public公共的可以使用可以使用可以使用可以使用

    Ø 总结:

​ 1.当属性没有要求时,建议:使用默认访问权限

​ 2.当要求使用封装完成,建议:实例变量编写为private访问权限

​ 3.当成员要求在当前类以及子类中使用, 建议:成员使用protected访问权限

​ 4.大多数情况下,方法使用public访问权限

  1. 重写 override也叫做覆盖

    • 在子类中重写父类的方法

    • 不能缩小父类的访问权限

    • 返回值类型一致 或者编写为父类方法返回值类型的子类类型

    • 方法名称必须一致

    • 参数列表必须一致

6 final 关键字修饰类

  • final 表示最终的
  • 可以修饰类、属性、方法
  1. final 关键字修饰类
  • 当使用final关键字修饰类,表示该类就是最终的类,也就是:不能被继承

  • 使用final修饰的类,比如:String System Scanner ……

  1. final 关键字修饰属性(重点):

    final关键字修饰属性
          2.1当使用final关键字修饰属性,称为常量
          2.2变量:存放数据,并且存放的数据是可以发生改变
             常量:存放数据,并且存放的数据是不可以发生改变
          2.3常量只有两种赋值方式:
                第一种方式:在声明同时赋值
        final static String name = null;
                第二种方式:通过构造方法完成赋值
          2.4一般final关键字与static关键字配合使用,原因:节省空间
          2.5常量名建议全部大写,如果有多个单词之间使用下划线隔开
             比如:数学中的π表示3.1415926 这个值固定的不变的,则在Java中建议编写为常量,一般使用PI表示Java中的π
    
  2. final 关键字修饰方法

    • 当使用final 关键字修饰方法,表示该方法是最终的,也就是:该方法不能被重写

7. 多态

  1. 多态的语法格式
父类类型 引用名 = new 子类();
注意:当前构成多态,引用名称是父类类型,父类中存放的是多个类中公共的属性和方法
    也就是说:引用名只能访问父类中公共的属性和方法,但是优先访问当前存放子类对象中重写以后的方法
  1. 什么是多态
多种不同的形态(结果)
多个对象调用同一个方法,得到多个不同的结果,原因:优先调用子类重写以后的方法
在现实生活中多态的案例,比如:理发师、裁缝、医生 ......都使用剪刀进行剪,得到不同的结果,比如:理发师剪头发,裁缝剪衣服,医生做手术......
  1. 满足多态的条件
子类继承父类
必须要在子类中重写父类的方法
父类类型 引用名 = new 子类();
  1. 多态的好处
    减少代码的冗余性(重复性),提高代码复用

  2. 多态中的两种类型转换(重点、难点)

    1. 当构成多态时,其实也就是向上转型,也叫做自动类型转换

    ​ 比如:Pet p = new Cat();

    ​ 也就是:由子到父

    ​ 当构成多态或者向上转型时,引用名是父类类型

    因此:只能访问父类中公共的属性和公共的方法,但是优先访问子类重写以后的方法

    1. 向下转型

      1. 什么时候进行向下转换或者强制类型转换?

      Ø 当构成多态时,如果访问子类独有的实例变量或独有的实例方法,则必须要进行向下转型也叫做强制类型转换

      Ø 其实也就是由父到子

当进行向下转型或者强制类型转换时,可能会出现类型转换异常

原因:
当前引用名中存放哪个子类对象,则就只能哪个子类类型,如果非要转换为其他的子类类型,则就出现类型转换异常

解决办法:

​ 在进行向下转型或者强制类型转换之前,建议先判断,如果满足则再向下转型或者强制类型转换

8. 提取方法

其实再IDEA中,也可以再main 方法中编写该题所有功能,然后将单独某个功能选中提取方法
提取方法操作步骤:
第一步:选中某一段单独功能的代码
第二步:按ctrl + alt + m
其中M表示Method方法

9. 抽象类和抽象方法(重点)

  1. 抽象类

    • 再Java中,类就是抽象的,也就是:不是具体的

      对象:具体的实例

    • 当创建宠物父类对象时,并没有明确得到的是猫对象,还是对象…

      ​ 因此宠物是父类,范围相对比较大,则就可以将父类编写为抽象类

    • 什么时候将类编写为抽象类?

      ​ 建议:将父类编写为抽象类,因为该类范围比较大,一般都创建子类对象;

    • 抽象类特点:

      1. 抽象类使用abstract关键字,其中abstract 表示抽象
      2. 抽象类是不能创建对象,因此得到:抽象类也是多态的一种形式
  2. 抽象方法

    • 不同宠物吃的东西不一样,因此:也就是需要子类重写吃的方法

    • 当创建子类对象时,再调用吃eat方法时,会优先调用子类重写以后的方法
      也就是:父类Pet中eat方法体使用不到,则就可以将父类中的方法编写为抽象方法

    • 什么时候将方法编写为抽象方法?
      当父类中的方法体,如果再子类中使用不到,则就可以将父类中的方法编写为抽象方法

    • 抽象方法的特点:

      ​ 4.1抽象方法使用abstract关键字
      ​ 4.2抽象方法必须没有方法体,也就是:不需要编写大括号,直接以英文分号作为结尾
      ​ 4.3抽象方法必须在抽象类中
      ​ 4.4子类继承抽象类时必须要重写抽象类中所有的抽象方法,否则子类也是抽象类
      ​ 大多数情况下,子类都会重写抽象类中所有的抽象方法
      ​ 4.5抽象类不能创建对象,也就是说:创建子类对象,因此得到抽象类也是多态的一种形式

10. 接口(重点)

  • 假如一个类中只编写抽象方法,具体如下:
public abstract class Pet{
	public abstract void eat();
}
  • 则就可以使用接口完成
  1. 接口的说明

    • 接口使用interface关键字

    • 接口中的抽象方法默认有 public abstract

    • 再Java中,类与类之间是继承,也就是:子类继承extends父类,并且是单继承
      再Java中,接口与类之间是实现,也就是:实现类实现implements 接口,并且是多实现

    • 当实现类实现接口时,必须重写接口中所有的抽象方法,否则实现类也是抽象类
      大多数实现类都重写接口中所有的抽象方法

    • 接口不能创建对象,也就是:接口也是多态的一种形式,也就是创建实现类对象

    • 接口也属于引用数据类型,在内存中存放的是地址(引用)

      接口

public interface Pet{
	void eat();
}
  1. 接口注意事项
  • 接口就是功能的封装
    例如:一个软件工程师既会编写代码,也会讲业务

  • 再JDK8.0 中,接口中包含:
    抽象方法(默认有 public abstract )
    公有静态常量(默认有public static final)
    public static 修饰的方法
    public default 修饰的方法

  • 在Java中,类与类之间是继承,也就是:子类继承父类,并且是单继承

    class A{
    }
    class B extends A{
    }
    

    在Java中,接口和接口之间是继承,也就是:子接口继承父接口,并且多继承

    interface X{
    }
    interface Y{
    }
    interface Z extends X,Y{
    }
    
    

    在Java中,类和接口是实现,也就是:实现类实现接口,并且是多实现

    interface A1{
    }
    interface B1{
    }
    class C1 implements  A1,B1{
    }
    //但是接口不能继承类
    
  • 在一个类中,如果既有继承也有实现,则继承必须位于实现的前面

    public class ** extends ** implements **,**{
      //  
    }
    
  • 抽象类与接口异同点

    1. 相同点

      • 抽象类和接口中都可以编写抽象方法

      • 子类或实现类必须要重写抽象类或接口中所有的抽象方法,否则子类或实现类也是抽象类

      • 抽象类和接口都不能创建对象,也就是说:抽象类和接口都是多态的一种形式,创建子类对象或者实现类对象

    2. 不同点

      Ø 抽象类

      • 使用abstract关键字

      • 抽象类中包含:普通类中包含的所有内容,也可以包含抽象方法

      • 子类继承抽象类,并且是单继承

      Ø 接口

      • 使用interface关键字

      • 在JDK8.0中, 接口中包含:
        抽象方法(默认有public abstract)、
        公有静态常量(public static final)、
        public static修饰的方法、
        public default修饰的方法

      • 实现类实现接口,并且是多实现

11. 内部类

  1. 什么是内部类?
    Ø 在一个类中再编写一个类,里面的这个类,称为内部类也叫做内置类或者叫做嵌套类

  2. 什么时候编写内部类

    Ø 一般内部类是对外部类提供服务,如果还想对其他外部类提供服务,则不建议编写内部类

    Ø 当一个大的数据结构中包含若干个小的数据结构,则就可以将这些小的数据结构编写为内部类

    n 比如:电脑中包含:内存条、硬盘、主板、CPU、风扇………

  3. 内部类的分类
    成员内部类
    静态内部类
    局部内部类

    public class MyClass {
        //编写实例方法
        public void print(){
            Inner i = new Inner();
        }
        class Inner{ //称为内部类,也叫做成员内部类,一般是在外部类的实例方法中使用
    
        }
    
        //编写静态方法
        public static void print2(){
            Inner2 i = new Inner2();
        }
        static class Inner2{ //称为静态内部类,一般在外部类的静态方法中使用
    
        }
    
        public void print3(){
            class Inner3{ //局部内部类
    
            }
        }
    }
    

    匿名内部类(重点、难点)

    • 匿名也就是没有名字

      /*
              注意:1.什么时候编写为匿名内部类?
                      当只创建一次对象时,则就可以编写为匿名内部类完成
                   2.匿名内部类其实也就是对内部类的简写形式
                   3.编写匿名内部类前提:必须继承父类或者实现接口
               */
              //Pet pet2 = new Pet(); //注意:出现编译错误,原因:宠物是接口不能创建对象
              Pet pet2 = new Pet(){
      
                  @Override
                  public void eat() {
                      System.out.println("正在吃......");
                  }
              };
              pet2.eat();
      
      public class Test2 {
          public static void main(String[] args) {
              /*Pet p = new Dog();
              p.eat();*/
              //其实上面两条语句也可以编写为一条语句完成,具体如下:
              new Dog().eat();
      
              //注意:当只创建一次对象,则也可以编写为匿名内部类完成
              new Pet(){
                  @Override
                  public void eat() {
                      System.out.println("正在吃Xxxxx");
                  }
              }.eat();
          }
      }
      

12. Object类(重点)

  1. Object类说明

Ø 在Java中,Object类是所有类的父类也叫做超类,要么直接继承Object类,要么间接继承Object类

Ø 当一个类没有使用extends指定继承哪个父类时,则系统默认继承Object类,也就是说:当继承Object父类时,extends Object是可有可无的

Ø 在java中,类具有传递性,也就是说:其实所有类都继承Object类中的方法

Ø API:Java帮助文档

  1. 常用方法(重点)

    • toString()方法
    public class Test {
        public static void main(String[] args) {
            //创建电脑对象
            Computer c = new Computer();
            /*
            通过运行得到:
                1.在默认情况下,只输出引用名(或者叫做对象名)c则输出:com.bjpowernode.demo8.Computer@4554617c
                  也就是说输出:完整类名@十六进制值
                2.原因:
                  在默认情况下,当只输出引用名时,系统默认调用toString()方法,输出c其实等价于c.toString()
                  当前引用名c是Computer类型,也就是调用toString()方法时,先在电脑类中找toString(),如果没有找到该方法,则再去父类Object中找toString()方法,
                  父类的方法体 return getClass().getName() + "@" + Integer.toHexString(hashCode());
                  因此得到:默认情况下,只输出引用名,其他调用的是Object类中的toString()方法
                          输出完整类名@十六进制值
             */
            System.out.println(c.toString()); //其实等价于c
    /*3.练习:当创建电脑对象后,只输出对象时要求输出该对象所有实例变量的值
                4.解决办法:调用toString()
                    父类Object中的toString()不能满足子类的要求,因此需要在子类中重写父类的toString()方法
                    重写方式如下:
                        第一种方式:光标放在子类中,按Ctrl + O选择父类中要重写的方法,然后按回车键,该方法体中默认调用的是父类中的方法,则需要手动编写代码实现相应功能,一般不常用
                        第二种方式:光标放在子类中,按Alt + Insert键,选择toString()方法,按回车键,比较常用
                5.重写toString()后,也就是将之前编写的print方法实现输出对象所有实例变量的值改为重写toString()*/
            c = new Computer("Lenovo", "黑色", 5688, 15.6);
            System.out.println(c); //其实等价于编写c.toString()
        }
    }
    
   //第一种方式:光标放在子类中,按Ctrl + O选择父类中要重写的方法,然后按回车键,该方法体中默认调用的是父类中的方法,则需要手动编写代码实现相应功能,一般不常用
       /*@Override
       public String toString() {
            return "品牌:" + this.brand + ",颜色: " + this.color + ",价格:" + this.price + ",尺寸: " + this.size;
       }*/
   
       @Override
       public String toString() {
           return "Computer{" +
                   "brand='" + brand + '\'' +
                   ", color='" + color + '\'' +
                   ", price=" + price +
                   ", size=" + size +
                   '}';
       }
  • equals(Objectobj)
   public class Test {
       public static void main(String[] args) {
           Person p1 = new Person("张三", 19, '男');
           Person p2 = new Person("张三", 19, '男');
           System.out.println(p1 == p2); //false 引用数据类型,使用==比较的是内存地址是否一致
           Person p3 = p1; //将p1赋给p3,也就是说:p1和p3存放同一个地址,指向同一个对象
           System.out.println(p1 == p3); //true
           /*
           练习题:比较实现两个对象中各个属性的值是否一致
           解决办法:使用equals方法完成
                   在默认情况下,引用名P1调用eqauls()方法时,先在Person类中找equals()方法,如果没有找到则再去父类Object中找equals方法
                   也就是说:在默认情况下,调用equals()方法其实执行的是Object类中的equals()方法,但是Object类中的equals()依然比较的是两个对象的内存地址是否一致,也就是:不能满足子类的需要,则需要在子类中重写父类的equals方法
                   重写方式有两种:
                       第一种方式:光标放在子类中安Ctrl + O 选择要重写的方法equals(),按回车键,该方法体默认调用的是父类中的方法,也就是:需要手动编写代码实现, 因此第一种方式不常用
                       第二种方式:光标放在子类中,按Alt + Insert选择第5项,实现比较两个对象中的各个属性的值是否一致,一致返回true,否则返回false
            */
           System.out.println(p1.equals(p2));
       }
   }

13. 类与类之间的语言

  • UML :统一建模语言
  • 常用的UML图:;类图、用例图、时序图……
  • 画UML图所使用的工具:visio 、starUML
  1. 继承(泛化)

Ø 子类继承父类 或者子接口继承父接口 is a

  1. 实现

Ø 实现类实现接口

  1. 依赖

Ø 如果A类中方法的返回值类型、参数列表、局部变量,使用到了B类,则称为A类依赖于B类

  1. 关联

Ø 如果A类中使用B类定义了成员变量,则称为A类关联B类

  1. 聚合

Ø 聚合也是关联的一种,如果A类中包含若干个B类,但是A类不能限定B类的生命周期,则称为A类为聚合类

  1. 组合

Ø 组合也是关联的一种,如果A类中包含若干个B类,但是A类能限定B类的生命周期,则称为A类为组合类

14. 递归(了解)

  1. 什么是递归?

Ø 在Java中,递归也就是:方法自己调用方法自己,必须满足某个条件程序结束

  1. 递归实现案例

Ø 使用递归完成,计算n!

public class Test {
    /*
    编写方法,使用递归完成,计算n!
    0! = 1
    1! = 1
     */
    public static int mul(int n){
        //判断形参n的值,如果为0或者为1则返回1
        if(n == 0 || n == 1){
            return 1;
        }
        return n * mul(n - 1);//重复调用nul方法
    }
    public static void main(String[] args) {
        System.out.println(Test.mul(3));
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天选之鸣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值