目录
1、取模
2、原码 反码 补码
3、final的作用
4、访问修饰符
5、面向对象的三大特征
封装
1、概念
2、好处
继承
1、概念
2、好处
3、细节
4、继承的本质
多态
1、概念
2、细节
1、取模
%取模的本质是: a%b --->本质是a-a/b*b
例如: -10%3 其实就是 -10-(-10)/3*3 结果:-1
额外注意的是
-10.5%3 当有小数进行取模的时候 本质是:-10.5-(int)(-10.5)/3*3=-1.5
2、原码 反码 补码
- 二进制的最高为是符号位:0代表正数 1代表负数
- 正数的原码、反码、补码是一样的
- 负数的反码=它的符号位不变,其他位进行取反
- 负数的补码= 反码+1 负数的反码=补码-1
- 0的反码 补码 都是0
- java没有无符号数,换言之,java中的数都是有符号的
- 在计算机运行的时候,都是以补码的方式来运算的
- 当我们要看运算结果的时候,要看它的原码
例题: ~2 求2的异或
1.写出2的原码 00000000 00000000 00000000 00000010
2.因为计算机运算的是补码,并且正数的原码 、反码 、补码三者是一样的
3.因此2的补码是 00000000 00000000 00000000 00000010
4.对2的补码进行异或,即11111111 11111111 11111111 11111101
5.最后得到的结果我们要看原码 因为是负数,我们先将补码-1变成反码
6.反码是 11111111 11111111 11111111 11111100
7.负数的原码是 符号位不变其他位取反
7.原码 10000000 00000000 00000000 00000011 得到的结果就是-3
3、final的作用
final关键字可以修饰:
(1)类。类不能被继承。
(2)方法。方法不能被重写,但是可以重载。
(3)基本类型变量。只能被赋值一次,即常量。
(4)引用。只有一次指向对象的机会。
注意final修饰的类是不可变的类 是错误的
类可不可变和类用没有用final修饰是没有直接关系的,而是要看它的底层源码。
常见的不可变类如String它是用final修饰的char数组来存储的源代码:
/** The value is used for character storage. */
private final char value[];
包装类型如Integer的源码:
private final int value;
public Integer(int value) {
this.value = value;
}
而StringBuffer和StringBuilde是用final修饰的但是它们就不属于不可变类源代码:
/**
\* The value is used for character storage.
*/
char[] value;
4、访问修饰符
java提供了四种访问修饰符号,用于控制方法和属性(成员变量)的访问权限(范围)
- 公共级别:用public修饰,对外公开
- 受保护界别:用protected修饰,对子类和同一个包中的类公开
- 默认级别:没有修饰符(或者叫缺省) ,向同一个包的类公开
- 私有级别:用private修饰,只有类本身可以访问,不对外公开
访问级别 | 访问修饰符 | 本类 | 同包 | 子类 | 不同包 |
公开 | public | √ | √ | √ | √ |
受保护 | protected | √ | √ | √ | × |
缺省(默认) | 没有修饰符 | √ | √ | × | × |
私有 | private | √ | × | × | × |
5、面向对象的三大特征
封装
1、概念
把抽象出来的数据(属性)和对象数据的操作(方法)封装在一起,数据被保护在内部。程序其他部分只能通过被授权的操作(方法),才能对数据进行操作
2、好处
- 隐藏实现细节
- 对数据进行验证,保证安全合理
继承
1、概念
主要解决代码复用性,使用extends关键字
注意:
- 子类自动拥有父类定义的属性和方法
- 父类有叫超类 基类
- 子类有叫派生类
2、好处
- 代码的复用性提高了
- 代码的扩展性和维护性提高了
3、细节
- 子类继承了父类的所有属性和方法(包括私有的),但是私有属性不能在子类中直接访问,要通过父类提供的公共方法才能去访问
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类对象的时候,不管子类使用那个构造器,默认情况下总会去调用父类的无参构造,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的那个构造器完成对父类的初始化工作,否则编译不通过。
- 如果希望指定去调用父类的某个构造器,则显式的调用一下:super(参数列表)
- super在使用的时候,只能放在构造器的第一行
- super()和this()都只能放在构造器的第一行,因此这两个方法不能共存在同一个构造器中
- java的所有类都是Object的子类 即Object是所有类的基类
- 父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类)
- 子类中最大只能继承一个父类(直接继承)。java是单继承机制
- 不能滥用继承,子类父类之间必须满足is - a的逻辑关系
- 例如: 柯基(子类)是一个狗(父类) 挪威那犬(子类)是一个狗(父类)
4、继承的本质
多态
1、概念
方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在分封装和继承基础之上的。
主要是提高代码的复用性,便于维护
举例
主人给自己动物喂食的例子 ---动物 ---狗 ---猫 ---食物 ---骨头 ---鱼肉 主人实现一个方法 给动物喂食物 发现 给狗喂骨头 要写一个方法 给猫喂鱼肉 也要写一个方法 如果后期还有的话 我们都要写一个方法 但是我们发现这个方法根本就是 给某个动物 喂某种食物 逻辑是相同的 但是我们确要写很多的方法,并且这些方法是大致相同的 因此引出了多态,用于提高代码的复用性,便于后期的维护
- 方法的重写和重载
- 对象的多态(核心)
一个对象的编译类型和运行类型可以不一致
编译类型在定义对象的时候,就确定了,不能改变、
运行类型是可以变化的
编译类型看定义时候等号的左面 运行类型看等号的右边
2、细节
- 多态的前提: 两个类是继承关系的
- 多态的向上转型:
- 本质:父类的引用指向子类的对象
- 语法:父类类型 引用名 = new 子类类型();
- 特点:编译的时候是父类类型 运行的时候是子类类型
- 可以调用父类所有成员(仍然遵循访问权限)、不能调用子类特有的成员
(编译期间,能调用那些成员,有编译类型绝对) - 最终运行效果看子类(运行类型决定)的具体实现
例:(对于重写的方法,最终调用的子类重写的方法)
- 多态的向下转型
- 语法:子类类型 引用名 = (子类类型)父类引用;
- 只能强制父类引用,不能强转父类的对象
(即堆中的父类对象不改变,只是改变了栈中的父类引用)
- 要求父类的引用必须指向的是当前目标类型的对象
例: Animal animal =new Cat() Cat cat =(Cat)animal;
(即其实输出的是动物类,但是你知道它是猫类,这个时候你可以直接强转成猫类)
- 当向下转型后可以就可以调用子类中的所有代码
- 属性没有重写一说 属性名看编译类型
属性跟方法是不同的,这点一定要注意
package com.sofwin.controller;
/**
* @packageName: com.sofwin.controller
* @author: wentao
* @date: 2022/10/20 14:28
* @version: 1.0
* @email 1660420659@qq.com
* @description: TODO
*/
public class Test0002 {
public static void main(String[]args){
A a=new B();
输出的10 属性没有重写一说,我们看的是编译类型 这一点跟方法是不一样的要记住
System.out.println(a.num);
B b=new B();
//输出20 看编译类型
System.out.println(b.num);
}
}
class A {
int num=10;
}
class B extends A {
int num=20;
}
- instanceOf 比较操作符
用于判断对象的运行类型是否为XX类型或XX类型的子类型
- java的动态绑定机制
- 当调用对象方法的时候,该方法会和该对象内存地址/运行类型绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用