顺序表和链表
- 概念
顺序表:顺序表底层是一个数组,在计算机内存中以一组地址连续的存储单元存储数据元素的数据结构。
链表:链表是一种由若干个独立节点组成的数据结构。每个节点由数据域和指针域组成。 - 区别
- 存储空间的分配方式
1 顺序表的底层是一个数组,因此顺序表无论是在逻辑上还是物理上均为连续的。
2 链表的物理存储单元是非连续、非顺序的,数据间的逻辑顺序由节点之间的指针相互连接实现。 - 优点
顺序表:
1 顺序表的物理和逻辑顺序均为连续,这说明顺序表在访问单个数据中存在优势,即第i个元素存储与第i个物理位置。因此顺序表可以依靠下标随机访问以及修改任何一个数据
2 顺序表无须为表示节点之间的逻辑关系而增加额外的存储空间**,提高了存储利用率**。顺序表可以方便地存储表中任何一个节点**,存储速度快**
链表:
1 链表可以方便地进行扩充。
2 链表可以方便地删除和插入。 - 缺点
顺序表:
1 顺序表的空间利用率低,源于顺序表存储结构的特点,顺序表在初始化过程中需要分配确定的存储空间,因此在无法确定数据个数时会造成存储空间的短缺和浪费的现象
2 顺序表的删除和插入效率低,由于顺序表的物理结构是连续的,因此在插入和删除某个节点后需要"善后":将操作节点之后所有元素的存储位置进行后移或前移。
链表:
1 存储利用率低。链表的每个节点除了数据域还需要指针域来实现节点间的逻辑连续。
2 访问和修改元素效率低。链表的物理存储单元非连续、非顺序导致了链表中元素的访问只能从一头开始顺序访问。
- 存储空间的分配方式
this和super
- 概念
this:JVM会给每个对象分配this,代表当前对象(存放当前对象的地址)
super:代表父类的引用,用于访问父类属性、方法、构造器 - 区别
区别点 | this | super | |
---|---|---|---|
1 | 访问属性 | 访问本类中的属性,如果本类没有此属性,则从父类中继续查找 | 从父类开始查找属性 |
2 | 调用方法 | 访问本类中给的方法,如果本类没有此方法则从父类继续查找 | 从父类中开始查找方法 |
3 | 调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
4 | 含义 | 表示当前对象 | 子类中访问父类对象 |
方法重写和方法重载
一. 概念
方法重载:在同一个类中写入多个参数列表不同但方法名相同的方法
方法重写:子类中对父类中某个方法功能的重新实现
二. 使用细节:
方法重载:
- 方法名必须相同
- 形参列表必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)
- 返回类型:无要求(即如果两个方法仅返回类型不同,不构成方法重载(会报错))
class Over{
正确的方法重载格式:方法名相同并且参数列表不同
public void f1(int n1,double n2){
System.out.println("传入两个参数");
}
public void f1(double n2,int n1){
System.out.println("与第一个相比交换传入两个参数");
}
public void f1(int n1){
System.out.println("传入一个参数");
}
public void f1(){
System.out.println("无参数传入");
}
”===============================================================“
错误的方法重载,仅改变返回类型不构成方法重载,会报错
public void f2(){}
public int f2(){
return 2;
}
}
方法重写:
- 子类的方法的参数、方法名称要和父类的参数、方法名称完全一样
- 子类方法的返回类型要和父类方法的返回类型一样或者是父类返回类型的子类(Object(父)---->String(子))(协变类型)
- 子类方法不能缩小父类方法的访问权限(private方法不能被重写)
- 静态(static)方法不能重写!!!
- final修饰的方法不能修改,更不能重写
class Person{
public void say(){
System.out.println("你好呀");
}
}
class Teacher extends Person{
重写的方法要用Override元注释去标记
正确的重写格式:方法名、参数名要完全相同,返回类型'最好相同'
@Override
public void say(){
System.out.println("学生好");
}
}
class Student extends Person{
@Override
public void say(){
System.out.println("老师好");
}
}
"=============================================================="
我们得知Object是所有类的父类,所以当子类重写父类的某个方法,
返回类型也可以是父类中该方法的返回类型的子类(协变类型)
class Person{
public Object say(){
System.out.println("你好呀");
return "hei";
}
}
class Teacher extends Person{
@Override
public String say(){
System.out.println("学生好");
return "hi";
}
}
”============================================================“
class Person{
public void say(){
System.out.println("你好呀");
return "hei";
}
}
错误的方法重写:子类中重写的方法的访问权限由public缩小至包权限(default默认权限)
class Teacher extends Person{
@Override
void say(){
System.out.println("学生好");
return "hi";
}
}
错误的方法重写:重写的方法不能由static或final修饰,
其原因是static成员是类加载时就初始化好的,而final方法明确规定不能被重写
class Student extends Person{
@Override
public static(final) void say(){
System.out.println("老师好");
}
}
三.底层本质
方法重载:方法重载其实是程序编译时的多态性,即代码在编译的时候就决定了使用哪一个方法,属于静态多态机制
方法重写:方法重写其实是代码运行时的多态性,即只有在代码真正运行的时候,才能决定到底使用哪一个真正的方法,属于动态多态机制