- 类和对象
- 一、封装
- 二、继承
- super和this的比较
- 方法的重写/覆盖
- 三、多态
- 四、类变量和类方法
- 1.类变量
- 2.类方法
- 五、main方法理解
- 六、代码块
- 七、final关键字
- 1.定义:用于修饰类、属性、方法和局部变量
- 2.使用情景:
- 3.使用细节
- 八、抽象类
- 1.定义:当父类的一些方法不能确定时,可以用abstract关键字来修饰,就可以不写方法体。
- 2.细节
- 九、接口
- 1.定义:接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候再根据具体情况实现方法。
- 2.细节
- 3.接口的多态特性
- 十、内部类
- 1. 分类 :(1)定义在类的局部位置 方法中或者是代码块中 -局部内部类 -匿名内部类 (2)定义在成员位置 -成员内部类 -静态内部类
- 2. 类的五大成员:属性、方法、构造器、代码块、内部类
- 3. 局部内部类的使用
- 4. 匿名内部类的使用
- 声明类变量的时候,不需要初始化;声明局部变量的时候,需要初始化
- 作用域不一样 类变量在整个类中都是可见;局部变量只在方法内可见。 在类中声明一个变量,在此类中的所有方法都是可以访问到的。在其他类中 访问不到本类中的变量。
在方法中声明变量,只能在本方法中被调用。
优先级:就近原则。 - 成员方法的传参机制(重要)
基本数据类型传递的是值,形参的改变不影响实参。
引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参。 - 方法重载(overload)
允许同一个类中多个相同方法名的存在。但要求形参列表不一致。
方法名:必须相同
形参列表:必须不同
返回类型:无要求
访问权限:无要求 - 可变参数
定义:java允许将同一个类中多个同名同功能但参数不同的方法封装成一个方法。
使用方法:访问修饰符 返回类型 方法名(数据类型… 形参名){}
注意:1.可变参数的实参可以为0个或任意多个
2.可变参数的实参可以为数组。
3.可变参数的本质就是数组。
4.可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后。
5.一个形参列表中只能出现一个可变参数
6. 构造器
1 构造器名和类名要相同 且没有返回值
2 一个类中可以有多个不同的构造器,即为构造器的重载
3 构造器是完成对象的初始化,不是创建对象。
4 在创建对象时 系统自动的调用该类的构造方法
5 如果程序员没有给出构造器,那么该类会默认生成一个无参构造器
6 一旦定义了自己的构造器,那么这个无参构造器就被覆盖了不能再使用。
6. this关键字
1 this关键字可以用来调用本类的属性方法和构造器
2 this用于区分当前类的属性和局部变量
3 访问成员方法的语法:this.方法名(参数列表);
4 访问构造器的语法: this(参数列表) 但是要注意只能在构造器中使用,即只能在构造器中去访问另一个构造器且必须放在第一条语句。
5 this不能再类定义的外部使用,只能在类定义的方法中使用
把类的属性隐藏起来,通过特定的方式访问,保证数据的安全性
- 把属性变为私有
- 添加getset方法
| public | protected | default | private | |
|---|---|---|---|---|
| 当前类 | Y | Y | Y | Y |
| 同包 | Y | Y | Y | N |
| 子孙类(同包) | Y | Y | N | N |
| 子孙类(不同包) | Y | YN可以修饰数据成员,构造方法,方法成员,不能修饰类(内部类除外) | N | N |
| 其他包 | Y | N | N | N |
1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类中直接访问,私有属性和方法只能通过间接的方式去访问
2. 子类必须调用父类的构造器完成父类的初始化工作
3. 当创建子类对象的时候,不管使用哪个构造器,默认情况下都会调用父类的无参构造器,如果父类中没有提供无参构造器,必须在子类中用super()指定调用父类的哪个构造器,完成对父类的初始化工作,否则编译不会通过。
4. super必须在构造器的第一行 同this() 因此这两个方法不能共存在同一个构造器
5. 所有的类都是object的子类 object是所有类的基类
6. 父类构造器的调用不限于直接父类!将一直往上追溯直到object顶级父类
7. 子类最多只能继承一个父类,即java是单继承机制
8. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系
9. super关键字
定义:super代表父类的引用,用于访问父类的属性、方法、构造器
当子类中有和父类重名的属性或者方法时,为了访问父类的成员,必须通过super。如果没有重名,通过this、super、直接访问是一样的效果。
super的访问不限于直接父类,往上追溯直到object类
| no. | 区别点 | this | super |
|---|---|---|---|
| 1 | 访问属性 | 访问本类中的属性,如果本类中没有此属性则从父类中继续查找 | 从父类开始查找属性 |
| 2 | 调用方法 | 访问本类中的的方法,如果本类中没有此方法则从父类中继续查找 | 从父类开始查找方法 |
| 3 | 调用构造器 | 调用本类的构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
| 4 | 特殊 | 表示当前对象 | 子类中访问父类对象 |
简单介绍:子类的方法和它父类的某一个方法的名称、返回类型、参数一样,那我们就说子类的方法覆盖了父类的方法。
注意事项
1. 子类的方法的参数、方法名称必须完成和父类的一样。
2. 子类方法的返回类型和父类的返回类型一样,或者是父类返回类型的子类。
3. 子类方法不能缩小父类的访问权限。可以扩大
(public>protected>默认>private)
| 名称 | 发生范围 | 方法名 | 形参列表 | 返回类型 | 修饰符 |
|---|---|---|---|---|---|
| 重载(overload) | 本类 | 必须一样 | 类型、个数、顺序至少有一个不同 | 无要求 | 无要求 |
| 重写(override) | 父子类 | 必须一样 | 必须相同 | 子类返回的类型和父类的一致或者是其子类 | 子类方法不能缩小父类的访问范围 |
static 修饰的属性或方法会在类加载的时候初始化
区别:
程序开始运行的时候,类加载器会加载类 同时加载类中的静态属性和方法
普通方法和属性是 在类实例化之后被加载
加载时机不同,静态属性和方法先被加载,普通方法和属性则是后被加载
这就解释了为什么静态方法不能访问普通方法。
严格来说,普通方法也会被立即加载 但是放入了方法区中,此时该方法是不可用的状态,只有当所属的类被加载之后才会变为可用状态。
静态方法和属性放入了堆的永久区 不会被垃圾回收机制回收。
静态方法生命周期长 普通方法生命周期短
三、多态-
方法的多态:重写和重载体现多态。
-
对象的多态:
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了不能改变
(3)运行类型是可以变化的
(4)编译类型看定义时 = 号的左边,运行类型看 = 号的右边
Animal animal = new Dog() #animal编译类型是Animal,运行类型是Dog!!!多态的前提是两个对象(类)存在继承关系
-
多态的向上转型
(1)本质:父类的引用指向了子类的对象
(2)语法:父类类型 引用名 = new 子类类型();
(3)特点:可以调用父类中的所有成员,不能调用子类中的特有成员,最终运行效果看子类的具体实现 -
多态的向下转型
(1)语法:子类类型 引用名 = (子类类型)父类引用;
(2)只能强转父类的引用,不能强转父类的对象
(3)要求父类的引用必须指向的是当前目标类型的对象
(4)可以调用子类类型的所有成员
注意事项:
-> 属性的值没有重写之说,属性的值看编译类型
-> instanceOf比较操作符 用于判断对象的运行类型是否为XX类型或XX类型的子类型
-> 方法看运行类型 属性看编译类型
-
java的动态绑定机制
(1)当调用对象方法得时候,该方法会和该对象的内存地址/运行类型绑定
(2)当调用对象属性时,没有动态绑定机制,哪里声明哪里使用 -
多态数组
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 -
多态参数
方法定义的形参类型为父类类型,实参类型允许为子类类型
- 定义:类变量也叫静态变量/静态属性,是该类的一个共享变量,任何一个类去访问或者修改的时候,这个值都是同一个值。
- 访问修饰符 static 数据类型 变量名 ;
- 类名.变量名
- 与普通变量的区别:类变量是所有类共享的 而普通变量是类独享的
- 类变量是在类加载的时候就初始化了,即使没有创建对象,只要类加载了就可以访问类变量。
- 类变量的生命周期是随着类加载开始,随着类消亡而销毁。
-
类方法和普通方法都是随着类的加载而加载,将信息结构储存在方法区,只不过普通方法在没有实例化对象之间的状态是不可用的,而类方法只要类加载就能够使用。
!类方法中没有this参数
!普通方法中隐含着this参数 -
类方法可以通过类名调用也可以通过对象名.方法名调用。而普通方法只能只能通过对象名.方法名调用
-
类方法中不允许使用和对象有关的关键字 比如this和super,而普通方法可以。
-
类方法中只能访问静态变量或者静态方法。
-
普通成员方法既可以访问非静态成员也可以访问静态成员,但必须遵守访问权限。
- main方法是由虚拟机调用的
- java虚拟机需要调用类的main方法,所以该方法的访问权限必须是public
- java虚拟机在执行main方法时不需要创建对象。所以该方法必须是static
- 该方法接收String 类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数
在main()方法中我们可以直接调用main方法所在类中的静态方法和静态属性
六、代码块但是不能直接访问该类中的非静态成员及方法,必须先创建类的一个实例化对象之后才能通过这个对象去访问类中的非静态成员
- 定义:代码块又称初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,用{}包围起来。但和方法不同,没有方法名、返回值、没有参数、只有方法体,且不通过对象或类显式调用,而是类加载时或创建对象时隐式调用。
- 修饰符可选,但只能选static ;号可以写上 也可以省略
- 好处:相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作
- 使用场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性。
- 注意事项
-
静态代码块作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次,如果是普通代码块,每创建一个对象,就执行。
-
类被加载的时机(重点):
- 创建对象实例时(new)
- 创建子类对象实例,父类也会被加载
- 使用类的静态成员时(静态属性/静态方法)
-
普通的代码块在创建对象实例时,会被隐式地调用。 被创建一次就会被调用一次。如果只是使用类的静态成员时,代码块并不会被执行。
-
创建一个对象时,在一个类中的调用顺序(难点):
- 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用) 。
- 调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用优先级一样,弱国有多个普通代码块和多个普通变量初始化,则按定义的顺序调用)。
- 调用构造方法。
-
构造器的最前面其实隐含了super()和调用普通代码块,静态相关的的代码块,属性初始化,在类加载时就执行完毕,因此是优先于构造器和普通代码块执行的。
-
优先级:
父类静态代码块和属性>子类的静态代码块和属性>父类的普通代码块和普通属性初始化>父类的构造方法>子类的普通代码块和普通属性初始化>子类的构造方法 -
静态代码块只能调用静态成员,普通代码块可以调用任意成员
- 当不希望类被继承时
- 当不希望父类的某个方法被子类重写时
- 当不希望某个类的属性被修改时
- 当不希望某个局部变量被修改时
- final修饰的属性又叫常量,一般用XX_XX_XX来命名
- final修饰的属性在定义时,必须赋初值,并且之后不能修改。赋值可以在直接定义、也可以在构造器中或者是代码块中
- 如果final修饰的属性是静态的,则初始化的位置只能是定义和代码块,不能在构造器中赋值。
- final修饰的类不能被继承,但是可以实例化对象。
- 如果类不是final类但是含有final方法,虽然方法不能被重写,但是可以被继承。
- 一般来说,一个类已经是final类了就没有必要再将方法修饰成final方法
- final不能修饰构造器
- final和static往往搭配使用,效率更高,不会导致类加载,底层编译器做了优化处理。
- 包装类(Integer,Double,Float,Boolean等都是final),String也是final类
2.细节是先有的抽象方法才后有的抽象类
- 抽象类不能被实例化
- 抽象类可以不包含abstract方法
- 一旦类包含了抽象方法,那么该类必须声明成abstract
- abstract只能修饰类和方法
- 抽象类的本质还是类,因此可以包含任意成员
- 抽象方法不能有主体,即不能实现
- 如果一个类继承了抽象类,那么必须实现抽象类的所有抽象方法
- 抽象方法不能用private、final、和static来修饰,因为关键字都是和重写相违背的。
接口时更加抽象的抽象类,抽象类里的方法可以有方法体,接口里的所有方法都没有方法体。接口体现了程序设计的多态和高内聚低耦合的的设计思想。
2.细节
后接口类可以有静态方法、默认方法,也就是说接口中可以有方法的具体实现
- 接口不能被实例化
- 接口中的所有方法是public方法,接口中抽象方法可以不用abstract修饰
- 一个普通类实现接口,就必须把该接口的所有抽象方法全都实现。
- 抽象类实现接口,可以不用实现接口的方法。
- 一个类可以同时实现多个接口
- 接口中的属性只能是final的,而且是public static final修饰符且必须初始化
- 接口中的属性访问方式:接口名.属性名
- 接口中不能继承其他的类,但是可以继承多个别的接口
interface A extends B,C{}
- 接口的修饰符只能是public和默认,这点和类的修饰符是一样的
- 多态参数,接口引用可以指向实现了接口的类的对象
- 多态数组:存放类的对象,除了可以调用usb接口定义的方法外还可以调用对象的特有方法(用 instance of)
- 接口存在多态传递现象
- 定义在外部类的局部位置,如方法中或者是代码块中
- 可以直接访问外部类的所有成员,包含私有的
- 不能添加访问修饰符,地位和局部变量一样,但可以用final修饰。作用域仅限方法中或者代码块中
- 局部内部类—访问---->外部类的成员 直接访问
- 外部类—访问---->局部内部类成员 创建对象再访问(必须在作用域内)
- 外部其他类—不能访问---->局部内部类
- 重名时遵循就近原则,如果要访问外部类的成员,则可以使用 外部类名.this.成员
- 本质上还是一个类同时也是一个对象,且没有名字
- 匿名内部类是定义在外部类的局部位置,比如方法中
new 类或接口(参数列表){ 类体};



