JavaSE超详细复习笔记(第五章-面向对象)

目录

一、面向对象概述

二、类与对象

三、包

四、成员变量

五、方法

1、概念理解

2、方法的分类

3、方法的声明

4、实例方法的调用

5、方法参数的值传递问题

6、方法重载Overload

7、方法的可变参数

8、方法的递归

六、对象数组

七、封装encapsulation

八、继承

九、方法重写Override

十、多态

十一、构造器

十二、非静态代码块(了解)

十三、实例初始化过程(了解)

十四、this和super关键字

十五、native和final关键字

十六、Object类

十七、标准JavaBean

十八、静态static


一、面向对象概述

  1. 面向对象是一种编程思想,参考现实中的事物,在程序中把所有的事物通过属性和功能进行描述。

  2. 面向对象与面向过程的比较:

    • 面向过程:

      关注点是步骤,如何做,程序员是执行者。

    • 面向对象:

      关注点是谁能做,由谁做。程序员是指挥者。

二、类与对象

  1. Java类:一类具体共同特征的事物的抽象描述,比如学生,汽车,手机;

  2. Java对象:一个具体的事物,比如:张三是一个学生对象,我的手机是一个具体的手机实体。

  3. 类与对象的关系:

    • 类是对象的模板,通过类可以创建对象。

    • 对象是类的具体实例。通过类创建对象的过程称为实例化。

  4. 类的定义格式:

    修饰符 class 类名{
       //类的成员:
        //属性-变量
        //功能-方法
    }
    //定义一个学生类
    public class Student{
        //属性-变量
        String name;
        int age;
        //功能-方法
        public void study(){
            System.out.println("学习....");
        }
    }
  5. 对象的创建

    类名 对象名 = new 类名();
    //创建一个学生对象
    Student stu = new Student();
    //使用对象
    stu.name = "tom";
    stu.age = 18;
    stu.study();

三、包

包在磁盘中表现为文件夹。

  1. 包的作用:

    • 避免类名的重复,这是类的全称是:包名+类名,比如:com.atguigu.Demo

    • 方便分类管理众多的类,比如java.lang包下是最核心的类

    • 配合权限修饰符实现访问权限管理

  2. 包的声明:

    定义类时必须声明类所在的包,使用关键字package,并且声明语句必须在当前文件的第一行。

    包名要符合标识符命名规范:即全小写字母组成,使用点.分隔开。

    package com.atguigu.test05method;
  3. 跨包使用类的问题

    在一个类中使用其他包下的类,需要导包,使用关键字import导包,写在当类声明之前,包声明之后。

    import java.util.Arrays;

    注意:java.lang包下的类可以直接使用,无需导包。

四、成员变量

Java类使用成员变量描述类的属性信息。

  1. 变量分类

    • 成员变量:声明在类的直接成员位置,与方法并列

      • 类变量-静态变量:有static修饰(后面讲)

      • 实例变量-非静态变量:没有static修饰

    • 局部变量:声明在方法中或参数上等局部区域。

      public class Student{
          //成员变量
          static String school;//类变量-静态变量
          String name;//实例变量-非静态变量
          
          //方法
          void test(int x){//变量x是局部变量
              int a = 10;//变量a是局部变量
          }
      }
  2. 实例变量的特点:

    • 实例变量必须通过对象来访问,访问方式:对象.实例变量

    • 实例变量值是每个对象独有一份

    • 实例变量有默认初始值,类同数组元素的默认初始值。

      Student stu = new Student();
      System.out.println(stu.name);//null 默认初始值
      stu.name = "tom";//
      System.out.println(stu.name);//tom
      ​
      Student stu2 = new Student();
      System.out.println(stu2.name);//null 默认初始值
      stu2.name = "张三";//
      System.out.println(stu2.name);//张三
  3. 实例变量的内存分析

  4. 实例变量与局部变量的区别

    实例变量局部变量
    声明的位置直接声明在类的成员位置声明在方法体中或其他局部区域内(方法声明上,构造方法,代码块等)
    修饰符public、private、final等不能使用访问权限修饰符,可以使用final
    内存加载位置
    初始化值有默认初始化值无默认初始化值
    生命周期同对象的生命周期随着方法的调用而存在,方法调用完毕即消失

五、方法

1、概念理解

  1. 方法是一个特定功能的代码块,把功能封装到方法中主要目的是重复利用代码。

  2. Java类使用方法来描述类的功能。

2、方法的分类

  1. 静态方法-类方法:有static修饰(后面讲),可以通过类名直接调用

  2. 非静态方法-实例方法:没有static修饰,必须通过对象调用。

3、方法的声明

  1. 方法声明的位置必须在类中方法外,在类的成员位置,所有方法声明必须是并列关系

  2. 声明格式:

    【修饰符】 返回值类型 方法名(【参数列表 】)【throws 异常列表】{
            方法体;
            【return 返回值;】
    }
  3. 格式说明:

    • 一个完整的方法 = 方法头 + 方法体。

      • 大括号内为方法体,主要来实现功能;

      • 大括号之前的内容是方法头,也称为方法签名。通常调用方法时只关注方法头即可。方法头包含5部分,有些部分可以缺省。

    • 修饰符: 修饰符后面详细讲,例如:public,static等都是修饰符

    • 返回值类型: 表示方法运行的结果的数据类型,与”return 返回值“搭配使用

      • 无返回值:void

      • 有返回值:可以是任意基本数据类型和引用数据类型

    • 方法名:给方法起一个名字,要符合标识符的命名规则,尽量见名知意,能准确代表该方法功能的名字

    • 参数列表:方法内部需要用到其他方法中的数据,需要通过参数传递的形式将数据传递过来,可以是基本数据类型、引用数据类型、也可以没有参数,什么都不写

    • throws 异常列表:可选,在异常章节再讲

    • 方法体:特定功能的代码

    • return:结束方法,可以返回方法的运行结果

      • 可以返回不同类型的数据,对应匹配的返回值类型

   - 如果方法无返回值,可以省去return,并且返回值类型为**void**
  1. 方法声明示例:

    public class Student{
        //方法:
        void test1(){
            
        }
        
        void test2(int a,String b){
            
        }
        
        String test3(){
            return "abc";
        }
        
        int test4(int a,int b){
            return a+b;
        }
    }

4、实例方法的调用

  1. 方法不调用不执行,调用一次执行一次。

  2. 实例方法必须通过对象来调用,调用方式:对象.实例方法(【实参列表】);

  3. 示例:

    Student stu = new  Student();
    stu.test1();
    stu.test2(10,"abc");
    String s = stu.test3();
    int sum = stu.test4(11,22);
    System.out.println(stu.test4(1,2));
  4. 方法调用的注意事项:

    1. 形参:方法声明上的形式参数。

    2. 实参:调用方法时传入的实际参数。方法调用时,实参列表必须与形参列表一致。

    3. 方法有返回值可以通过变量接收,也可以直接输出,如果即没有接收也没直接输出会丢失返回值。

    4. 方法如果没有返回值不能使用变量接收,也不能直接输出。

  5. 本类内部实例变量和实例方法调用问题

    public  class Student{
        //实例变量
        String name;
        int age;
        //实例方法
        public void show(){
            System.out.println(name);//访问的是属性name,实例变量
            System.out.println(age);//访问的是属性age,实例变量
            System.out.println(this.name);//访问的是属性name,实例变量
            System.out.println(this.age);//访问的是属性age,实例变量
            //this代表当前对象,即谁调用此实例方法,this就代表谁
        }
        
        public void hello(){
            show();//直接调用本类的实例方法show方法
            this.show();//通过this调用本类其他实例方法show方法
        }
        
        public void test(String name){//这里使用this可以区分局部变量name和实例变量name
            System.out.println(name);//访问局部变量name
            System.out.println(this.name);//访问实例变量name
        }
    }
  6. 方法调用的内存分析

5、方法参数的值传递问题

  1. 方法参数为基本数据类型,形参的改变不会影响实参

  2. 方法的参数为引用数据类型,形参的改变可能会影响实参

  3. 特殊情况:形参为引用数据类型的String或包装类类型。

6、方法重载Overload

 方法重载: 同一个类中(本类声明的或继承自父类的)的方法,方法名相同,参数列表不同的情况,这就叫方法重载。
参数列表不同: 指的是参数个数不同,数据类型不同,数据类型顺序不同。

方法的重载与重写的区别 , 我有单独写一篇文章介绍 , 可以在主页找来看下

7、方法的可变参数

在JDK1.5之后, 如果我们定义一个方法时,此时某个形参的类型可以确定,但是形参的个数不确定,那么我们可以使用可变参数。

	//示例
// 可变参数写法
	public  int getSum(int... arr) {
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		return sum;
	}

注意:

(1)一个方法最多只能有一个可变参数

(2)如果一个方法包含可变参数,那么可变参数必须是形参列表的最后一个

8、方法的递归

  1. 方法的递归:方法自身调用自己的情况

  2. 递归的分类:

    • 直接递归:方法自己直接调用自己

    • 间接递归:方法间接调用自己,比如:方法A调用B,B调用A

  3. 递归的使用注意事项:

    • 递归一定要有出口(结束条件),否则就是无穷递归,类似死循环。会导致内存溢出。

    • 递归即使有出口,也不宜递归次数太多,否则还是会导致内存溢出。

  4. 示例:

    //求n!
    //1*2*3*...*(n-1)*n
    //f(n)= f(n-1) * n
    //f(1)=1
    public int jiecheng(int n){
        if(n==1){
            return 1;
        }
        return jiecheng(n-1)*n;
    }
  5. 内存分析:

六、对象数组

数组的元素是对象(引用数据类型)

//创建Student类型的数组,用于存储多个Student对象
Student[] stus = new Student[3];
Student stu = new Student();
stus[0] = stu;
stus[1] = new Student();
stus[2] = new Student();

七、封装encapsulation

  1. 封装:通俗的讲,封装就是把该隐藏的隐藏起来,该暴露的暴露出来。那么暴露的程度如何控制呢?就是依赖访问控制修饰符,也称为权限修饰符来控制。

    便于使用者正确使用系统,防止错误修改属性
    有助于系统之间的松耦合,提高系统独立性
    提高软件的可重用性
    降低了构建大型系统的风险
  2. 权限修饰符:

    权限修饰符共有4种,分别为public,protected、缺省、private;权限修饰符可以使得数据在一定范围内可见或者隐藏。

    修饰符本类本包其他包子类任意位置
    private×××
    缺省××
    protected×
    public

    权限修饰符可以修饰:

    外部类:public和缺省

    成员变量、成员方法、构造器、成员内部类:public,protected,缺省,private

  3. 类的封装

    • 属性全部私有化

    • 提供公共的get,set方法

    public class Student{
        //私有属性
        private String name;
        private int age;
        //公共的getter和setter
        public void setName(String name){
            this.name = name;//this表示当前对象
        }
        public String getName(){
            return name;
        }
        //.....
        //可以通过IDEA快捷模板生成get和set方法:alt + insert  ——》选择getter,setter -->选择属性
    }

八、继承

  1. 概念理解:Java类有父类和子类的区别,子类可以继承父类的成员变量和方法。

  2. 继承的格式:

    先有父类再有子类,在定义子类时确定与父类的关系,使用关键字extends

    【修饰符】 class 子类 extends 父类{
        //子类成员
    }
    //父类--超类,基类
    public class Animal{}
    //子类-派生类
    public class Cat extends Animal{}
  3. 继承的好处:

    • 提高了代码的复用性

    • 提高了代码块的扩展性。

    • 是多态的前提

      弊端:增强了类与类的耦合度

  4. 继承的特点:

    • 子类会继承父类的所有成员变量和方法,但是不能直接访问父类的私有成员。

    • 如果子类要访问父类的私有成员,可以通过提供公共的方法来访问。

    • Java类只支持单继承,即一个类只能有一个直接父类。

    • 一个类可以有多个子类

    • Java类支持多层继承,一个类B可以继承自类A,C类还可以继承自B类。

九、方法重写Override

  1. 概念理解:子类中声明了与父类相同的方法,通常方法体不同。

    //父类--超类,基类
    public class Animal{
        public void eat(){
            System.out.println("动物吃饭....");
        }
    }
    //子类-派生类
    public class Cat extends Animal{
        @Override//注解,用于验证此方法是否是重写的方法,如果不是编译失败。
        public void eat(){
            System.out.println("猫吃鱼...")
        } 
    }
  2. 方法重写的具体要求:

    • 子类的方法名和参数列表必须与父类的一致

    • 子类方法的返回值类型必须【小于等于】父类方法的返回值类型(小于其实就是是它的子类,例如:Cat< Animal)。

      注意:如果返回值类型是基本数据类型和void,那么必须是相同

    • 子类方法的权限必须【大于等于】父类方法的权限修饰符。

      注意:public > protected > 缺省 > private

      父类私有方法不能重写

      跨包的父类缺省的方法也不能重写

    另外:

    静态方法不能被重写,方法重写指的是实例方法重写,静态方法属于类的方法不能被重写,而是隐藏。

    final修饰的方法不能被重写

    私有方法也不能被重写。

十、多态

  1. 多态的理解:一个事物在不同环境或条件下呈现不同的特征状态。

  2. 多态的语法形式:父类引用指向子类对象

    父类类型  变量 =  子类对象
    Animal a = new Cat();
    a = new Dog();
  3. 多态的表现

    编译看左边,运行看右边。

    Animal a = new Cat();
    a.eat();//编译时看左边父类Animal中是否有eat方法,运行时执行的是右边子类Cat的eat重写的方法
  4. 多态的好处:

    • 提高了代码的扩展性

    • 降低了类与类之间的耦合度

  5. 多态的应用

    • 应用在方法的参数上或成员变量

      public void feed(Animal a){//形参为Animal类型,实参可以是Animal的任意子类对象
          a.eat();
      }
    • 应用在数组

      Animal[] as = new Animal[3];
      as[0] = new Animal();
      as[1] = new Cat();
      as[2] = new Dog();
    • 应用在方法的返回值类型

      public Animal sale(String type){
          if("cat".equals(type)){
              return new Cat();
          }else if("dog".equals(type)){
              return new Dog();
          }
          return null;
      }
  6. 向上转型与向下转型

    • 子类类型对象可以自动向上转换为父类类型

    • 把父类类型变量转换为子类类型,需要强制转换。但是强制转换有风险,可能发生类型转换异常ClassCastException

      多态引用时,不能直接调用子类的特有方法,可以通过强制向下转型来调用子类的特有方法。

      Cat cat = new Cat();
      ​
      ​
      Animal a = cat;//自动向上转型
      Cat c = (Cat)a;//强制向下转型
      ​
      Animal a2 = new Dog();
      Cat c2 = (Cat)a2;//这里运行时会发生类型转换异常。
  7. 关键字instanceof

    用于判断变量或对象的运行时类型是否属于某种类型。

    Animal a2 = new Dog();
    //Cat c2 = (Cat)a2;//这里会发生类型转换异常。
    if(a2 instanceof Cat){
        Cat c2 = (Cat)a2;
        c2.catchMouse();//调用Cat的特有方法
    }else if(a2 instanceof Dog){
        Dog d = (Dog) a2;
        d.lookDoor();//调用Dog类的特有方法
    }
  8. 虚方法

    虚方法:就是可以被重写的方法。调用原则:编译看左边运行看右边。

    • 静态分派:编译期在左边父类中找到最匹配的方法。

    • 动态绑定:运行时,执行之前确定的最匹配方法的重写方法。

    非虚方法:比如静态方法,final修饰的方法等不能被重写的方法,编译看左边,运行也看左边。

    成员变量:编译运行都看左边,理解为不具有多态性

十一、构造器

  1. 构造器的作用:用于new对象时为实例变量赋值。

  2. 构造器的语法格式:

    【权限修饰符】 类名(【参数列表】){
        //构造器体
    }
    public class Student{
        //属性
        String name;
        int age;
        //空参构造器
        public Student(){}
        //有参构造器
        public  Student(String name,int age){
            this.name = name;
            this.age = age;
        }
    }

    格式说明:

    • 修饰符只能是权限修饰符

    • 构造器名称必须与当前类名相同

    • 构造器类似方法,所以也称为构造方法

    • 构造器没有返回值,void也不能有。

    • 构造器可以重载

  3. 构造器的使用

    new 构造器名(【参数】);
    Student stu = new Student();//使用空参构造器创建对象
    Student stu2 = new Student("tom",18);//使用两个参数的构造器创建对象

    使用说明:

    • 每个类中默认自带一个空参构造器。

    • 一旦显示给出一个构造器,默认的空参构造器不再存在。

    • 构造器不能继承

  4. this和super调用构造器

    • this(【参数】) :用于调用本类的其他构造器,必须用在构造体内第一行

    • super(【参数】):用于调用父类的构造器,必须在构造体内第一行

    • 通过构造器创建子类对象时,一定会先调用父类构造器初始化父类数据。

    • 每个构造器内默认自带super()用于调用父类构造器。当显示给出this(【参数】)或者super(参数)时,默认的super()不再存在。

十二、非静态代码块(了解)

  1. 作用:跟构造器一样通常是为实例变量赋值

  2. 格式:在类中定义{}

    public class Student{
        String name;
        int age;
        //非静态代码块-实例化代码块
        {
         //为实例变量赋值的代码
        }
    }
  3. 执行特点:

    调用任意一个构造器都会执行。并且一定优先于构造器执行。

十三、实例初始化过程(了解)

  1. 实例初始化过程:即创建对象的过程,主要是为实例变量赋值的过程。

  2. 实例初始化方法:

    当通过构造器new对象时。代码底层会执行一个实例初始化方法init{},调用任何一个构造器都会执行此次方法,此方法包含4部分内容:

    1. 构造器内第一行super(【参数】)

    2. 实例变量的直接显示赋值语句

    3. 非静态代码块中语句

    4. 构造体内其余代码

    执行过程:首先执行的一定是super(【参数】),2,3部分按照代码书写顺序执行。最后执行构造体内其余代码。

十四、this和super关键字

  1. this关键字

    表示当前对象

    • 应用在实例方法,构造器等地方

    • 使用方式:

      this.实例变量或实例方法 :表示调用当前对象的实例变量或方法

      this(【参数】) :表示调用本类的其他构造器

  2. super关键字

    用于访问父类数据的一个关键字

    • 应用在实例方法、构造器等地方

    • 使用方式:

      super.实例变量或实例方法 :表示调用父类的成员

      super(【参数】) :表示调用父类的构造器

  3. this和super访问成员变量和方法遵从原则:

    就近原则和追根溯源原则

十五、native和final关键字

  1. native关键字

    本地的,用于修饰方法,是本地方法,方法体是c/c++编写,我可以直接调用或重写。

  2. final关键字

    最终的,不可修改的

    • 修饰变量是常量

    • 修饰的方法不能被重写

    • 修饰的类不能被继承

      //此类不能被继承
      public final class Student{
          //此方法不能被重写
          public final void test(){
              //此变量是常量
              final int x = 10;
          }
      }

十六、Object类

java.lang.Object类是根父类,即是所有Java类的父类。

常用方法:

  1. int hashCode(); 返回对象的哈希值,此方法是为了提高哈希表性能。

    此方法默认返回是对象的内存地址转换而来的一个整数。建议子类重写此方法,使其返回值与对象的属性相关。

  2. Class getClass(); 返回对象的运行时类型。

    对象.getClass().getName() 返回对象的运行时类型名称(字符串)

  3. String toString(); 返回对象的字符串形式。即把对象转换为字符串返回。

    默认返回的是对象的运行时类型名称+'@'+对象的哈希值的16进制形式

    建议所有Java类都重写此方法,用于返回对象的属性信息。

    System.out.pritnln(对象)等价于System.out.pritnln(对象.toString())

  4. boolean equals(Object obj); 此方法用于比较两个对象是否相等

    默认此方法用于比较两个对象的内存地址是否相等。

    建议子类重写此方法,用于比较对象的内容是否相同。

  5. void finalize();此方法由垃圾回收器调用,通常用于释放一些c/c++占用的释放资源。

十七、标准JavaBean

编写Java类的一般标准规范。

  1. 类应该是具体的,公共的

  2. 应该提供无参构造器

  3. 属性应该私有化,并提供公共的getter,setter方法

  4. 实现序列化接口Serializable

十八、静态static

静态是随着类的加载而加载。

  1. 成员变量

    • 静态变量-类变量:有static修饰

      是所有对象共享的一份数据,通常通过类名来访问,类名.静态变量,存在内存的方法区

    • 非静态变量-实例变量:没有static修饰

      是每个对象独有一份实例变量值,必须通过对象来访问,对象.实例变量,存储在堆中

    • 静态类变量和非静态实例变量、局部变量

      静态变量实例变量局部变量
      声明的位置直接声明在类的成员位置直接声明在类的成员位置声明在方法体中或其他局部区域内(方法声明上,构造方法,代码块等)
      修饰符必须static,还可以public、private、final等可以public、private、final等不能使用访问权限修饰符,可以使用final
      内存位置方法区
      初始化值有默认初始化值有默认初始化值无默认初始化值
      生命周期和类相同同对象的生命周期随着方法的调用而存在,方法调用完毕即消失
  2. 静态方法

    有static修饰的方法是静态方法,或称为类方法

    • 访问方式:

      静态方法建议通过类名直接访问,类名.静态方法,不推荐使用对象访问。

      实例方法必须通过对象来访问

    • 特点:

      静态方法不能被重写,称为覆盖。

      静态方法在多态引用形式下,编译运行都看左边父类类型。

  3. 静态代码块

    static修饰的代码块,通常用于为静态变量赋值等

    执行特点:在类加载过程中执行,并且只执行一次,优先于非静态代码块的执行。(非静态代码块new调用构造器时就会执行,每次调用都会执行)

    public class Student{
        //静态变量
        static int x;
        //静态代码块
        static{
            x = 123;
        }
    }
  4. 类的初始化

    类的初始化只在类加载过程中完成的,类初始化的目的主要是为静态变量赋值。类初始化时会在底层执行一个clinit{},此方法包含2部分内容:

    1. 静态变量的直接显示赋值语句

    2. 静态代码块中语句

    这两部分代码块按照书写先后顺序执行。

    注意:

    • 类的初始化只执行一次,并且优先于实例化。

    • 一个类要初始化,如果其父类还未初始化先初始化父类。

  5. 本类内静态与非静态相互访问问题

    1. 静态不能直接访问非静态

    2. this和super是与对象相关的,不能使用在静态域中

      public class MyClass{
          static int x = 10;//静态变量
          int y = 20;//非静态变量
          
          //实例方法
          void testInstance(){
              System.out.println("实例方法...");
          }
           //静态方法
         static void testStatic(){
              System.out.println("静态方法...");
          }
          
          //实例方法
          void test1(){
              System.out.println(x);
              System.out.println(y);
              testInstance();
              testStatic()
          }
          //静态方法
          static void test2(){
              System.out.println(x);
             // System.out.println(y);//不能直接访问非静态变量
             // testInstance();//不能直接访问实例方法
              testStatic()
              //System.out.println(this);不能使用this
            //super.toString();//不可以使用super
          }
          
      }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值