包:
- 什么是包? 可以把它理解为一个文件夹
- 包的作用? 区分相同名称的类,方便管理类,控制访问范围
- 如何创建包?和创建文件夹一样
- 如何引入包?语法:import 包 , 如:import java.util.*
- 如果有两个一样的类名,就可以提供地址来区分是哪个包下的

- 包的命名规范:
- 只能包含数字,字母,下划线,小圆点
- 不能以数字开头,不能用关键字,保留字
- 正规格式:com.公司名.项目名.业务名
- 常用的包:
- java.lane.* 是java的基础包,默认导入不需要引入
- java.util.* java提供的工具包
- java.net.* 网络开发包
- java.awt.* java页面开发包
- 细节:
- package(打包) - 作用:生明当前类是属于哪个包
- import(导入) - 作用:导入包
访问修饰符:
- 什么是访问修饰符? 用于控制方法和属性的访问权限
- 访问修饰符分为:4种访问修饰
- public - 公共的
- protected - 受保护的
- private - 私有的
- 默认的 - 就是什么都不写

- 细节:
- 修饰符,可以修饰属性和方法以及类
- 只有默认和public才能修饰类
- 属性和成员属性的访问完成一样
- //细节2:只有默认和public才能修饰类
- public class Sds {
- public int i = 1; //公共
- protected int n = 2;//受保护的
- int o = 3;//默认的
- private int p = 4;//私有的
- public void show(){ //方法和属性的访问修饰符是一样的
- System.out.println("我是方法show");
- }
- }
- //细节2:只有默认和public才能修饰类
- class King{
- }
复制代码 封装:
- 什么是封装? 将类在的某些信息隐藏在类的内部,不允许外部直接访问,而是通过类提供的方法来对隐藏的数据进行访问和操作
- 封装的好处? 1.只能规定的方法访问和操作数据 ,2.可以对数据进行验证,保证安全合理,3.隐藏实现细节
- 封装的实现步骤:
- 将属性私有化private
- 提供一个setXxx(参数列表)方法,对属性进行判断和赋值
- 提供一个getXxx()方法,获取属性值
- public class Test{
- private String name;
- private String sex = "男";
- private int age = 18;
- //获取属性值
- public String getName() {
- return name;
- }
- public void setName(String name) {
- //进行判断和赋值
- if(name.length() > 1 && name.length() < 5){
- this.name = name;
- }else {
- System.out.println("你名称太长了");
- }
- }
- public String getSex() {
- return sex;
- }
- public void setSex(String sex) {
- this.sex = sex;
- }
- }
- main{
- Test.setName("jack,彭于晏,吴彦祖");//肯定是错的,因为条件判断最大是5
- }
复制代码- 构造器和Set()方法结合:
- 如果使用构造器来给属性赋值,那么Set方法的判断就会失效,直接在构造器中调用Set方法就可以经解决
- public Sds2(String name, String sex, int age) {
- //像使用构造器,就可以直接跳过Set()的判断了
- // this.name = name;
- // this.sex = sex;
- //调用本类的方法就好set方法就好了
- setName(name);
- setSex(sex);
-
- }
复制代码 继承:
- 什么是继承? 符合is a条件的类可以通过继承来解决代码的复用,如动物类和小狗类,那么小狗就可以继承动物类,因为狗有动物的行为
- 为什么需要继承?减少代码的复用
- 继承示意图:
- 继承的基本语法:
- class 子类 extends 父类{
- //继承父类,知道要有父类的属性和方法
- }
复制代码
- 细节:
- 子类继承了父类,非私有的属性和方法可以直接在子类访问,但私有属性不能直接访问(需要通过父类的公共方法来访问)
- 子类必须调用父类的构造器,完成父类的初始化(理解:当去继承父类如果没调用构造器初始化父类,那么继承的是什么?)
- 创建子类对象,不管使用子类哪个构造器,默认会去调用父类的无参构造器,如果父类没有无参构造器,则需要在子类使用super来指定父类构造器,完成父类初始化
- 指定父类构造器方法:super(参数列表)
- super()使用时必须放在构造器第一行(super()只能在构造器中使用),因此super和this都是需要放在第一行的,所以不能同时在一个构造器使用
- java所有类都是Object类的子类,所以父类可以一直追溯到Object
- java是单继承机制,只能继承一个父类
- 父类和子类必须满足is-逻辑,如你是飞机类去继承汽车类,这不就扯蛋了
- public static void main(String[] args) {
- B b= new B();
- }
- class A{
- A(){
- System.out.println("我是A的无参构造器");
- }
- A(String mame) {
- System.out.println("我是A的有参构造器");
- }
- }
- class B extends A{//只能继承一个父类
- B(){
- //super();默认调用父类的无参构造器
- //super("jack");指定父类的构造器
- System.out.println("我是b的无参构造器");
- }
- }
复制代码
- 继承的本质:
- 本质:先去加载父类,在加载子类
- 问题:为什么创建的CarSon指向的堆中有父类的属性?
- 细节中说到:因为继承了父类就会获取子类中非私有的属性和方法
Super关键字:
- 什么是Super关键字? 可以用于直接访问父类的构造器、方法、属性
- 理解:本类不访问直接访问父类
- class Car{
- String name = "汽车";
- String affect = "出行";
- }
- class CarSon extends Car{
- String name = "跑车";
- String CarName = "Lamborghini";
- public void jk(){
- System.out.println("CarSon类jk方法");
- }
- public void show(){
- System.out.println(affect);//如果没指定调用的是父类的还是子类的,就从子类开始向上找
- System.out.println(name);//输出跑车,这个也等价于this.name
- System.out.println(super.name);//输出汽车
- }
- }
复制代码- 细节:
- 如不使用super,就从本类向父类查找成员,如果有重名就遵循就近原则,本类没有才找父类
- 找成员naem,如子类没有找父类,父类没有在找爷爷类。A->B->C,当然遵守访问权限原则

方法的重写/覆盖:
- 什么是方法的重写? 就是子类的某个方法和父类的某个方法,方法名称、返回类型、参数列表一样
- 细节:
- 子类的形参列表,方法名称,要和父类形参列表,方法名称完全一样
- 子类的返回类型要和父类一致,或保持父子关系,如父类是Object返回类型,子类是String返回类型
- 子类不能缩小方法的访问权限但是可以放大 public > protected > 默认 > private
- class Car{
- public void show(){
- System.out.println("我是show方法");
- }
- public Object show2(){
- return 1.1;
- }
- private void show3(){
- System.out.println("我是show3方法");
- }
- }
- class CarSon extends Car{
- //子类的形参列表,方法名称,要和父类形参列表,方法名称完全一样
- public void show(){
- System.out.println("我是子类,我重写了show方法");
- }
- //子类的返回类型要和父类一致,或保持父子关系,如父类是Object子类是String
- public String show2(){
- return "1.1";
- }
- //子类不能缩小方法的访问权限但是可以放大 public > protected > 默认 > private
- public void show3(){
- System.out.println("我是子类,我重写了show3方法");
- }
- }
复制代码

多态:
- 什么是多态? 多种形态,多态是建立在继承和封装的基层上
- 理解:完成某个行为的时候,不同的对象去完成会产生不同的状态
- 例子:方法的重写和重载就是多态的一种体现 -> 方法的多态
- 如父类引用=子类对象( 如:Animal animal = new Dog() ) - > 对象的多态
- 对象的多态:
- Animal animal = new Animal( ) - -> 左边是编译类型 - 右边是运行类型
- 一个对象的编译类型和运行类型可以不一致,当然只两者要保持继承关系
- 编译类型在确定对象后是不能改变的,运行类型可以改变
- 下面案例中就使用对象的多态完成了动物的喂食问题
- 小狗有父类,食物有父类,通过小狗和食物的父类编译类型去引用它的子类对象完成操作
- public class Test {
- public static void main(String[] args) {
- person person = new person("汤姆");
- Dog2 dog2 = new Dog2("小白");
- Bone2 bone2 = new Bone2("骨头");
- person.show4(dog2,bone2);
- //解决:用到多态对象就完美的解决该问题喂食方法的重复问题
- Cat2 cat2 = new Cat2("小花");
- Bone2 bone3 = new Bone2("骨头");
- person.show5(cat2,bone3);
-
- }
- }
- //目的:让人去给动物喂食物
- class Animal2{
- private String name;
- public Animal2(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- class Fish2{
- private String name;
- public Fish2(String name) {
- this.name = name;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- class Dog2 extends Animal2{
- public Dog2(String name) {
- super(name);
- }
- }
- class Cat2 extends Animal2{
- public Cat2(String name) {
- super(name);
- }
- }
- class Bone2 extends Fish2{
- public Bone2(String name) {
- super(name);
- }
- }
- class person{
- public person(String name) {
- this.name = name;
- }
- private String name;//主人名称
- //问题:如果我有一百种小动物,那我的喂食方法也需要写一百个吗
- public void show4(Dog2 dog2,Bone2 bone2){ //喂食方法
- System.out.println("主人"+name+"给"+dog2.getName()+"吃"+bone2.getName());
- }
- //解决:用到多态对象就完美的解决该问题
- public void show5(Animal2 animal2,Fish2 fish2){ //喂食方法
- System.out.println("主人"+name+"给"+animal2.getName()+"吃"+fish2.getName());
- }
- }
复制代码
- 多态向上转型:
- 什么是向上转型? 子类是运行类型,父类是编译类型
- 细节:
- 不能调用本身的特有成员,可以调用父类的所有成员(遵守访问权限)
- 为什么不能调用本身特有成员? 因为在编译阶段,能调用哪些成员,是由编译类型决定(说白了就是加载编译类型的成员变量)
- 因为最终的的运行看子类的具体表现
- 因为最终的的运行看子类的具体表现什么意思? - 调用成员时还是按子类向父类的向上查找
- public class Test {
- public static void main(String[] args) {
- //普通继承 - 可以调用本身特有的成员,和父类中所有的成员(遵守访问权限)
- Dog2 dog2 = new Dog2();
- dog2.eat();//吃骨头
- dog2.action();
- dog2.show();
- //多态向上转型 - 不能调用本身的特有成员,可以调用父类的所有成员(遵守访问权限)
- //为什么不能调用本身特有成员? 因为在编译阶段,能调用哪些成员,是由编译类型决定(说白了就是加载编译类型的成员变量)
- //Animal2是编译类型,Dog2是运行类型
- //为什么animal2.eat();输出吃骨头不是吃东西? - 因为最终的的运行看子类的具体表现
- //因为最终的的运行看子类的具体表现什么意思? - 调用成员时还是按子类向父类的向上查找
- Animal2 animal2 = new Dog2();
- animal2.eat();//吃骨头
- }
- }
- class Animal2{
- public void eat(){
- System.out.println("吃东西");
- }
- public void action(){
- System.out.println("撒娇");
- }
- }
- class Dog2 extends Animal2{
- public void eat(){
- System.out.println("吃骨头");
- }
- public void show(){
- System.out.println("展示才艺");
- }
- }
复制代码
- 多态向下转型:
- 什么是向下转型? 把父类的的引用强转,为编译类型是子类的对象( 如:Dog dog = (Dog)animal )
- 细节:
- 只能强转父类的引用,终于不是父类的对象
- 强转的父类引用必须是和当前对象有关联的
- 向下转型后,可以调用子类中所有的成员
- Animal2 animal2 = new Dog2();
- animal2.eat();//吃骨头
- //多态的向下转型 - 强转需要保持关联性
- //当初是Dog2向上转型为父类的animal2,那么向下转型也要保持这个关系
- Dog2 dog3 = (Dog2) animal2;
- og3.show();
复制代码
- 属性没有重写之说:
- 属性的值看编译类型 -
- public class Test {
- public static void main(String[] args) {
- A a = new B();
- System.out.println(a.name);//MIUI
- B b = new B();
- System.out.println(b.name);//Huawei
- }
- }
- class A{
- public String name = "MIUI";
- }
- class B extends A{
- public String name = "Huawei";
- }
复制代码
- instanceOf比较操作符:
- 用与判断对象的运行类型是否为XX类型或XX类型的子类型
- public class Test {
- public static void main(String[] args) {
- A a = new A();
- System.out.println(a instanceof A);//真
- A a2 = new B();
- B b = new B();
- System.out.println(b instanceof A);//真
- }
- }
- class A{
- public String name = "MIUI";
- }
- class B extends A{
- public String name = "Huawei";
- }
复制代码
- java的动态绑定机制(重点):
- 什么是动态绑定机制?
- 当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明哪里使用
- public class Test {
- public static void main(String[] args) {
- A a = new B();
- //没有把B类中的sum()方法注销时的输出结果
- System.out.println(a.sum());//220
- System.out.println(a.sum1());//210
- //把B类中的sum()方法注销后输出的结果
- //为什么是210? 因为地态绑定机制的原因,调用到getl()时就回到运行类型的调用,没有该方法在往上寻找
- System.out.println(a.sum());//210
- System.out.println(a.sum1());//210
- }
- }
- class A{
- public int a = 100;
- public int sum(){
- return getl() + 10;
- }
- public int sum1(){
- return a + 10;
- }
- public int getl(){
- return a;
- }
- }
- class B extends A{
- public int a = 200;
- // public int sum(){
- // return a + 20;
- // }
- public int sum1(){
- return a + 10;
- }
- public int getl(){
- return a;
- }
- }
复制代码- 多态数组:
- 什么是多态数组? 在一个数组中可以存放不同的子类
- 案例:
- public class Test {
- public static void main(String[] args) {
- Person[] person = new Person[5];
- person[0] = new Student("小白",18,"学生");
- person[1] = new Teacher("老王",32,"老师");
- for (int i = 0; i < person.length; i++) {
- //show方法是重写的 - 但运行结果是根据运行类型
- if(person[i] != null){
- String show = person[i].show();
- System.out.println(show);
- //向下转型,调用特有的成员
- if(person[i] instanceof Student){
- System.out.println(((Student)person[i]).study());
- }
- if(person[i] instanceof Teacher){
- System.out.println(((Teacher)person[i]).teach());
- }
- }
- }
- }
- }
- class Person{
- public Person(String name, int age) {
- this.name = name;
- this.age = age;
- }
- private String name;
- private int age;
- public String show(){
- return name+"-"+age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
- class Student extends Person{
- public Student(String name, int age, String job) {
- super(name, age);
- this.job = job;
- }
- private String job;
- public String show(){
- return super.show()+"-"+job;
- }
- public String study(){
- return super.getName()+"在收听java";
- }
- }
- class Teacher extends Person{
- public Teacher(String name, int age, String job) {
- super(name, age);
- this.job = job;
- }
- private String job;
- public String show(){
- return super.show()+"-"+job;
- }
- public String teach(){
- return super.getName()+"给学生将java";
- }
- }
复制代码 Object顶级父类下的常见方法:
- equals方法:
- equlas:是Object类中的方法,默认(没被重写时)是判断引用类型的地址是否相等,子类往往重写该方法用与判断内容是否相等(如String和Integer)
- 一般 equals 和 == 会进行一个比较(面试):
- == :是一个比较运算符
- == :即可以判断该基本数据类型,又可以判引用类型
- ==:判断基本数据类型判断该的值,判断的是引用类型判断该的是地址
- 重写equals方法:
- public class Test {
- public static void main(String[] args) {
- Person person1 = new Person("小白",18,'男');
- Person person = new Person("小白",18,'男');
- // System.out.println(person1.equals(person));//false(没有重写equals默认比较地址)
- System.out.println(person1.equals(person));//true(重写equals后)
- }
- }
- class Person{
- public Person(String name, int age, char sex) {
- this.name = name;
- this.age = age;
- this.sex = sex;
- }
- String name;
- int age;
- char sex;
- public boolean equals(Object obj) {
- //this代表的就是obj(自己调用我自己)
- if(this == obj){
- return true;
- }
- if(obj instanceof Person){
- Person p = (Person)obj;
- return this.name == p.name && this.age == p.age && this.sex == p.sex;
- }
- return false;
- }
- }
复制代码
- hashCode方法:
- hashCode返回的是哈希码值,支持该方法是为了提高哈希表
- 哈希值主要根据地址类(但哈希值不完全等价于地址,因为Object的hashCode方法会根据不同的对象返回不同的整数)
- 两给引用,指向的是同一个对象,则哈希值肯定是一样,反知
- public class Test {
- public static void main(String[] args) {
- Person person1 = new Person("小白");
- Person person2 = new Person("小红");
- System.out.println(person1.hashCode());//356573597
- System.out.println(person2.hashCode());//1735600054
- }
- }
- class Person{
- public Person(String name) {
- this.name = name;
- }
- String name;
复制代码
- toString方法:
- 默认返回:全类名+@+哈希值的十六进制
- 一般子类重写用来返回对象的属性信息,打印对象或拼接对象时,都会该方法会自动调用
- public class Test {
- public static void main(String[] args) {
- Person person1 = new Person("小白","打游戏");
- // System.out.println(person1.toString());//默认输出
- System.out.println(person1);//重写输出:Person{name='小白', hobby='打游戏'}
- }
- }
- class Person{
- public Person(String name, String hobby) {
- this.name = name;
- this.hobby = hobby;
- }
- String name;
- String hobby;
- @Override
- public String toString() {
- return "Person{" +
- "name='" + name + '\'' +
- ", hobby='" + hobby + '\'' +
- '}';
- }
- }
复制代码
- finalize方法:
- finalize方法是做什么的? 当对象被回收时,系统自动调用该方法(注意不是该方法用来回收对象,而是在被回收前做一些操作)
- 什么时候被回收?当对象没有引用指向它时,jvm认为该对象就是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁前会调用finalize方法
- 垃圾回收机制?是由GC算法来决定(也就是说对象没引用的时候就马上销毁,而是由GC算法决定的),但是可以通过System.gc();来主动触发垃圾回收机制
- public class Test {
- public static void main(String[] args) {
- BaoMa baoMa = new BaoMa("宝马");
- baoMa = null;
- System.gc();//主动调用垃圾回收机制
- System.out.println("程序退出");
- }
- }
- class BaoMa{
- public BaoMa(String name) {
- this.name = name;
- }
- String name;
- @Override
- protected void finalize() throws Throwable {
- System.out.println("销毁汽车"+name);
- System.out.println("释放资源");
- }
- }
复制代码
断点调试:
- 什么是断点调试? 通过一行一行的去执行代码,查看代码的执行

- 类加载的断点调试演示:

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |