目录
一、包
1.1 包的定义
1.2 导入包中的某个类
1.2.1 静态导入
1.3 包的访问权限(default)
1.4 常见的系统包
二、继承
2.1 语法规则
2.2 继承访问权限(protected)
2.3 super关键字
2.4 super和this的区别
2.5 final关键字(终结器)
三、多态
3.1 向上转型
3.2 方法重写(覆写/覆盖)
3.3 向下转型
3.4 多态的好处
3.5 在构造方法中调用重写的方法
四、抽象类
4.1 语法规则
4.2 抽象类的作用
五、接口
5.1 语法规则
5.2 接口的应用场景
5.3 JDK内置两大接口
5.4 抽象类与接口比较
一、包
1.1 包的定义
包:是组织类的一种方式,就是一个文件夹,使用package定义一个包,主要目的是解决类名称重复问题。
包的命名规则:和项目命名规则相同,全部小写,多个单词使用下划线分隔。
1.2 导入包中的某个类
包:是组织类的一种方式,就是一个文件夹,使用package定义一个包,主要目的是解决类名称重复问题。
包的命名规则:和项目命名规则相同,全部小写,多个单词使用下划线分隔。
1.2 导入包中的某个类
①使用java.util.Date引入java.util这个包中的Date类:
②使用import语句导入:
③将java.util这个包中的类全部导入:
④当两个包中都有相同名称的类时:
1.2.1 静态导入
使用 import static 可以导入包中的静态的方法与字段:
1.3 包的访问权限(default)
包的访问权限:仅对当前包中同级目录下的类可见,不同包包括子包都不行。
1.4 常见的系统包
包的访问权限:仅对当前包中同级目录下的类可见,不同包包括子包都不行。
java.util:Java工具包(Arrays,Date,jcf):ArrayList,HashMapjava.lang:基础语言开发包(System)java.net:网络编程开发包(Socket)
二、继承
2.1 语法规则
继承:当 class A is a B,说明此时A是天然的B的子类,此时就可以使用继承结构。
基本语法:
class 子类 extends 父类{
}
继承:当 class A is a B,说明此时A是天然的B的子类,此时就可以使用继承结构。
基本语法:
class 子类 extends 父类{
}
使用extends继承父类子类会继承父类中所有public和protected域(属性和方法)父类中的private属性和方法子类无法访问一个子类只能继承一个父类,不允许多继承,允许多重继承
2.2 继承访问权限(protected)
protected作用域:在同一个包中具有继承关系的子类、不同包中具有继承关系的子类和同一个包中的类可见。
四种访问权限的比较:
2.3 super关键字
1.super修饰属性:
super.属性名称:直接从父类中找到该属性
2.super修饰方法:
① super调用普通方法:super.方法名称(参数列表); 表示直接从父类中调用该方法
② super调用构造方法:super(参数列表);
注意:在子类中使用super调用父类的构造方法时和子类this构造调用互相矛盾,只能用一个。
2.4 super和this的区别
1.super修饰属性:
super.属性名称:直接从父类中找到该属性
2.super修饰方法:
① super调用普通方法:super.方法名称(参数列表); 表示直接从父类中调用该方法
② super调用构造方法:super(参数列表);
注意:在子类中使用super调用父类的构造方法时和子类this构造调用互相矛盾,只能用一个。
2.5 final关键字(终结器)
final关键字的功能:限制类被继承。
final修饰属性,表示该属性为常量(值不能修改,类型也不能变)final修饰类,表示类不能有子类final修饰方法,表示该方法无法被覆写
三、多态
多态:一个引用可以表示多种状态
3.1 向上转型
多态:一个引用可以表示多种状态
向上转型基本语法:
父类 引用名称=new 子类实例();
由上图可得,调用fun方法时,只要对象是Animal本身或子类都可以传入fun方法(向上转型)。
向上转型发生在三个地方:
- 产生对象时:Animal cat=new Cat();方法传参时:如上图中fun方法方法返回,如下图:
动态绑定:在Java中,调用某个类的方法,究竟执行了哪段代码(是父类方法的代码还是子类方法的代码),要看究竟这个引用指向的是父类对象还是子类对象,这个过程是程序运行时决定的。
3.2 方法重写(覆写/覆盖)
方法覆写:在有继承关系的类之间,子类定义了和父类完全相同的方法,并且参数的类型和个数完全相同,这种方法就称为覆写。
方法覆写的三个要求:
只能重写成员方法/实例方法,不能重写静态方法(static)。子类方法的权限修饰符>=父类方法,例如:父类中是public,子类中只能是public;父类中是default,子类中可以是default或public。方法覆写的返回值必须相同,至少是向上转型的返回值
注意:在方法覆写时,不能出现private权限,包访问权限一定要特别小心,要注意子类和父类是否时相同的包。
重载和覆写区别:
3.3 向下转型
向下转型:父类对象转成子类对象。
例如:
如图所示,animal.eat(); //eat()在Animal中定义了,在Dog中覆写了,animal引用是通过Dog类new出来的,所以调用的是Dog类中的eat;
animal.run(); //Animal类中没有run这个方法,这个方法是Dog独有的,因此我们需要通过向下转型,将animal还原为Dog。如下图:
instanceof:instanceof关键字返回一个布尔值,表示一个引用是否是一个类的实例。
3.4 多态的好处
降低使用者的使用门槛方便扩展:
3.5 在构造方法中调用重写的方法
一段有坑的代码:创建两个类,A为父类,B为子类,B中重写了func方法,并且在A的构造方法中调用func。
package letter;
public class A {
public A(){
this.func();
}
public void func(){
System.out.println("A的func");
}
}
package letter;
public class B extends A{
private int num=10;
public B(int num){
this.num=num;
}
public void func(){
System.out.println("B的func,num="+num);
}
public static void main(String[] args) {
B b=new B(100);
}
}
构造B对象的同时,会调用A的构造方法A的构造方法中调用了func方法,此时会触发动态绑定,会调用B中的func方法此时B对象自身还没有构造,此时num处于未初始化的状态,值为0
四、抽象类
4.1 语法规则
抽象类:是普通类的超集,只是比普通类多了一些抽象方法而已。在当前类中不知道具体实现,要延迟到具体子类中实现,它存在的意义就在于让子类覆写,来实现具体功能。
在draw方法前面加上abstract关键字,就表示这是一个抽象方法,抽象方法没有方法体(没有{}),不能执行具体代码。对于包含抽象方法的类,必须加上abstract关键字表示这是一个抽象类。
注意:
- 抽象类无法直接实例化对象,例如 Shape shape=new Shape();//错 子类继承抽象类,必须覆写抽象类中的所有抽象方法(子类为普通类)。抽象类任然可以有构造方法和普通方法等(普通类有的,抽象类都有),子类仍然遵循对象的实例化流程,先调用父类构造方法。抽象类必须有子类:final abstract 不能同时出现;抽象方法必须被覆写:private abstract 不能同时出现。子类继承抽象类,任然满足 is a 原则。抽象类仍然是单继承局限,一个类只能继承一个抽象类。
4.2 抽象类的作用
作用:抽象类存在的最大意义就是为了被继承,抽象类本身不能被实例化,要想使用,只能创建该抽象类的子类,然后让子类覆写抽象类中的抽象方法。
使用抽象类的场景就如上面的代码,实际工作不应该由父类完成,而应由子类完成,那么此时如果不小心误用成父类了,使用普通类编译器是不会报错的,但是父类是抽象类就会在实例化的时候提示错误,让我们尽早发现问题。
五、接口
5.1 语法规则
接口:接口是抽象类的更进一步,抽象类中还可以包含非抽象方法和字段,而接口中只有全局常量和抽象方法(JDK8之前,JDK8扩展了default方法)。
接口使用原则:
- 子类使用implements实现接口,一般接口的命名使用I开头和类做区分,子类实现接口可以使用Impl结尾,表示是接口的子类。接口中只有public权限,接口中只有全局常量和抽象方法,只有在接口中abstract,static,final,public都可以省略掉(接口内部)。接口的多实现,接口没单继承限制,子类可以同时实现多个父接口,子类在实现多个父接口时,使用逗号分隔。接口仍然不能直接实例化对象,必须通过子接口来向上转型(同抽象类)。子类若同时继承父类,实现接口请先试用extends继承一个父类,而后使用implements实现多个接口(子类实现接口没有is a原则,is a原则只是描述类之间的继承)。
5.2 接口的应用场景
1.定义规范/标准
例如USB接口:
package computer;
import java.util.concurrent.Callable;
public class Computer {
public void plugIn1(USB port1){
port1.setUp();
port1.work();
}
public void plugIn2(USB port2){
port2.setUp();
port2.work();
}
public static void main(String[] args) {
Computer computer=new Computer();
computer.plugIn1(new Mouse());
computer.plugIn2(new KeyBoard());
}
}
2.表示一种能力或行为
5.3 JDK内置两大接口
1.java.lang.Comparable
当我们给对象数组排序时,就需要实现Comparable接口,并实现其中的compareTo方法,使其具备可比较性:
package student;
import java.util.Arrays;
public class Student implements Comparable{
private String name;
private int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public static void main(String[] args) {
Student[] students=new Student[]{
new Student("张三",18),
new Student("李四",19),
new Student("王五",23),
new Student("赵六",24),
};
Arrays.sort(students);
System.out.println(Arrays.toString(students));
}
@Override
public String toString() {
return "Student{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
public int compareTo(Object o) {
Student s=(Student)o;
if(this.ages.age){
return 1;
}else{
return 0;
}
}
}
在sort方法中会自动调用compareTo方法,compareTo方法的参数时Object,传入的就是Student类型的对象,然后比较当前对象和参数对象的大小关系:
如果当前对象大于参数对象,返回小于0的数如果当前对象小于参数对象,返回大于0的数如果当前对象和参数对象不分先后,返回0
2.java.lang.Cloneable:克隆接口
程序的克隆:复制一个新的对象,新的对象的属性值是从旧对象中拷贝过来的。
浅拷贝:
b1.a.num=100; 对与b2也是可见的,所以b1.a和b2.a指向了相同的对象,通过clone拷贝出来的b对象只是拷贝了b本身,而没有拷贝内部包含的a对象,此时b1和b2中包含的a引用仍然是指向同一个对象的,此时修改一边,另一边也会发生改变,这种拷贝就是浅拷贝。



