1. 对象简介
万物皆对象,而类可以理解为是对某一类事物的描述或者说对象的模板。
实例化出来的对象的实际数据存储在堆内存中,变量只是在栈内存中存储了对象实际数据在堆内存中的地址,所以当多个对象变量指向同一个对象实际数据时,修改其中一个对象变量,也会影响其他变量的值。
2. this关键字
this就是一个变量,指向当前类的对象,哪一个对象中的方法用到this,this指向的就是哪个对象。
3. 构造器(构造方法)
构造方法是一种特殊的方法,没有返回值,方法名必须和类名相同。
构造方法是一种用于创建对象的方法,例如 new Student() 就是在执行构造方法去创建对象。
构造方法注意事项:
- 在设计一个类时,如果不写构造方法,Java自动生成一个无参的构造方法。
- 如果自己定义了有参构造方法,Java将不再生成无参的构造方法,需要的话需要自己写。
4. 封装性
面向对象的核心点就是封装,将数据和数据的处理方式,都封装到对象中。
封装的设计规范:合理隐藏、合理暴露
体现在代码中就是将不想让外界直接访问的变量使用private修饰,被private修饰的变量或者方法只能在本类中被访问。
如果想获取或设置被private修饰的变量,就得调用对外暴露(public修饰)的set/get方法,在这个方法中可以对调用者传过来的数据进行一些控制,更加安全。代码示例如下:
// 学生类
class Student{private String name;public void setName(String name){this.name = name;}public String getName(){return name;}
}public class Test01 {public static void main(String[] args) {Student stu = new Student();stu.setName("张三");System.out.println(stu.getName());}
}
5. 实体类JavaBean
实体类就是一种特殊的类,它满足下面的要求:
- 类中的成员变量都要私有,并且要对外提供相应的getXxx、setXxx方法
- 类中必须要有一个公共的无参构造器
JavaBean实体类仅仅是用来封装数据的,只提供对数据进行存取的方法。
应用场景:例如实体类可以作为MyBatis查询数据库时的数据返回类型,用于接收从数据库中查询到的数据。
6. 静态(static)
可以用来修饰成员变量,也可以用来修饰成员方法。
6.1 static修饰成员变量
Java中的成员变量按照有无static修饰分为两种:类变量、实例变量。它们的区别如下:
- 类变量:有static修饰,属于类,在计算机中只有一份,被类的全部对象共享。
- 实例变量(对象的变量):无static修饰,是属于每个对象的。
由于静态变量是属于类的,只需要通过类名就可以调用:类名.静态变量
实例变量是属于对象的,需要通过对象才能调用:对象.实例变量
6.2 static修饰成员方法
成员方法根据有无static也分为两类:类方法、实例方法
有static修饰的方法,是属于类的,称为类方法;调用时直接用类名调用即可。
无static修饰的方法,是属于对象的,称为实例方法;调用时,需要使用对象调用。
类方法是随着类的加载而加载的,而实例变量、实例方法是随着对象的创建而产生的,所以不能在static修饰的类方法中调用实例方法或使用实例变量。
6.3 static应用(代码块)
代码块根据有无static修饰分为两种:静态代码块、实例代码块
静态代码块:
- 格式:static{}
- 特点:类加载时自动执行,由于类只会加载一次,所以静态代码块也只会执行一次。
- 作用:完成类的初始化,例如:对类变量的赋值。
实例代码块:
- 格式:{}
- 特点:每次创建对象时,执行实例代码块,并在构造器前执行。
- 作用:和构造器一样,都是用来完成对象的初始化的,例如:对实例变量进行初始化赋值。
7. 工具类
如果一个类中的方法全都是静态的,那么这个类中的方法就全都可以被类名直接调用,由于调用起来非常方便,就像一个工具箱,所以把这样的类就叫做工具类。
8. 继承
Java中提供了一个关键字extends,使用这个关键字,可以让一个类和另一个类建立起父子关系。
public class A extends B{ // A继承了B,B称为父类,A称为子类。}
继承的特点
- 子类能够继承父类的非私有成员(成员变量、成员方法)
- Java语言只支持单继承,不支持多继承,但是可以多层继承。
继承后对象的创建
- 子类的对象是由子类、父类共同完成的。
继承的好处
- 减少重复代码的编写,提高代码的复用性。
- 同时也方便了代码的管理,当需要修改某个公共的属性名时,直接在父类中修改一下即可。
9. 权限修饰符
什么是权限修饰符呢?
- 权限修饰符是用来限制类的成员(成员变量、成员方法、构造器...)能够被访问的范围
缺省就是default
10. 方法重写
什么是方法重写
当子类觉得父类方法不好用,或者无法满足父类需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。
在使用子类调用方法时,遵循就近原则,即如果子类中有相应的可调用方法就调用子类的,如果子类没有就调用父类中相应的方法。可通过super关键字指定要调用父类的成员变量或者方法,如super.name、super.toString()等。
11. this和super的用法总结:
访问本类成员:
- this.成员变量 //访问本类成员变量
- this.成员方法 //调用本类成员方法
- this() //调用本类空参数构造器
- this(参数) //调用本类有参数构造器
访问父类成员:
- super.成员变量 //访问父类成员变量
- super.成员方法 //调用父类成员方法
- super() //调用父类空参数构造器
- super(参数) //调用父类有参数构造器
注意:this和super访问构造方法,只能用到构造方法的第一句,否则会报错。
12. 多态
什么是多态?
多态是在继承、实现情况下的一种现象,表现为:对象多态、行为多态。
简单来说,即两个子类继承同一个父类,然后两个子类对父类的某个方法做了重写,然后当我们调用这个被重写的方法时,不同的子类就会有不同的表现。
13. final关键字
final关键字是最终的意思,可以修饰类、修饰方法、修饰变量。
- final修饰类:该类称为最终类,特点是不能被继承。
- final修饰方法:该方法称之为最终方法,特点是不能被重写。
- final修饰变量:该变量只能被赋值一次。
在实际运用当中经常使用final来定义常量,什么是Java中的常量呢?
- 被 static final 修饰的成员变量,称之为常量。
- 通常用于记录系统的配置信息
14. 抽象类
在Java中有一个关键字叫abstract,它就是抽象的意思,它可以修饰类也可以修饰方法。
- 被abstract修饰的类,就是抽象类
- 被abstract修饰的方法,就是抽象方法(不允许有方法体)
抽象类的特点:
- 不能通过抽象类去创建对象。
- 可以作为父类让子类去继承,而且子类继承抽象的父类时必须实现抽象父类的所有抽象方法。
- 子类继承父类如果不复写父类的抽象方法,要想不出错,这个子类也必须是抽象类
抽象类可以解决多个子类有相同代码的问题:
- 第1步:定义一个抽象类,把子类中相同的代码写成一个模板方法。
- 第2步:把模板方法中不能确定的代码写成抽象方法,并在模板方法中调用。
- 第3步:子类继承抽象类,只需要重写父类抽象方法就可以了。
15. 接口
什么是接口?
- 接口只能包含成员变量和抽象方法。
- 接口是用来被类实现(implements)的,我们称之为实现类。
- 一个类是可以实现多个接口的(接口可以理解成干爹),类实现接口必须重写所有接口的全部抽象方法,否则这个类也必须是抽象类。
接口到底有什么好处呢?主要有下面的两点
- 弥补了类单继承的不足,一个类同时可以实现多个接口。
- 让程序可以面向接口编程,这样程序员可以灵活方便的切换各种业务实现。
15.1 接口JDK8的新特性
从JDK8开始,接口中新增的三种方法形式。我们看一下这三种方法分别有什么特点?
public interface A {/*** 1、默认方法:必须使用default修饰,默认会被public修饰* 实例方法:对象的方法,必须使用实现类的对象来访问。*/default void test1(){System.out.println("===默认方法==");test2();}/*** 2、私有方法:必须使用private修饰。(JDK 9开始才支持的)* 实例方法:对象的方法。*/private void test2(){System.out.println("===私有方法==");}/*** 3、静态方法:必须使用static修饰,默认会被public修饰*/static void test3(){System.out.println("==静态方法==");}void test4();void test5();default void test6(){}
}
接下来我们写一个B类,实现A接口。B类作为A接口的实现类,只需要重写抽象方法就可以了,对于默认方法不需要子类重写。代码如下:
public class B implements A{@Overridepublic void test4() {}@Overridepublic void test5() {}
}
最后,写一个测试类,观察接口中的三种方法,是如何调用的
public class Test {public static void main(String[] args) {// 目标:掌握接口新增的三种方法形式B b = new B();b.test1(); //默认方法使用对象调用// b.test2(); //A接口中的私有方法,B类调用不了A.test3(); //静态方法,使用接口名调用}
}
在多实现、继承和实现并存时,有可能出现方法名冲突的问题,需要了解怎么解决:
- 一个接口继承多个接口,如果多个接口中存在相同的方法声明,则此时不支持多继承
- 一个类实现多个接口,如果多个接口中存在相同的方法声明,则此时不支持多实现
- 一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会有限使用父类的方法
- 一个类实现类多个接口,多个接口中有同名的默认方法,则这个类必须重写该方法。
16. 匿名内部类
匿名内部类本质上是一个没有名字的子类对象、或者接口的实现类对象。
下面就是匿名内部类的格式:
new 父类/接口(参数值){@Override重写父类/接口的方法;
}
比如,先定义一个Animal抽象类,里面定义一个cry()方法,表示所有的动物有叫的行为,但是因为动物还不具体,cry()这个行为并不能具体化,所以写成抽象方法。
public abstract class Animal{public abstract void cry();
}
接下来,我想要在不定义子类的情况下创建Animal的子类对象,就可以使用匿名内部类
public class Test{public static void main(String[] args){//这里后面new 的部分,其实就是一个Animal的子类对象//这里隐含的有多态的特性: Animal a = Animal子类对象;Animal a = new Animal(){@Overridepublic void cry(){System.out.println("猫喵喵喵的叫~~~");}}a.eat(); //直线上面重写的cry()方法}
}
匿名内部类的作用:简化了创建子类对象、实现类对象的书写格式。
17. 枚举
更新中...