1. Static关键字
概述
1. 使用static关键字修饰的内容,属于类,不在属于对象或者方法.凡是创建的本类对象,都共享static修饰的成员变量,或者方法
修饰成员变量、成员方法
1. 如果一个成员变量使用static关键字修饰,那么这个成员变量不在属于对象自己,而是属于所在类,多个对象共享同一份数据
2. 如果一个成员方法使用static修饰,那么就成了静态方法,静态方法不属于对象,而属于类
注意: 如果没有static修饰,那么必须先创建对象,然后通过对象来使用
使用static修饰的可以通过,类名.来调用
使用对象名.静态方法,在javac编译后会翻译成: 类名.静态方法
在本类中使用静态方法,可以省略类名,直接进行调用
静态修饰的不能访问非静态内容(静态的在内存中先加载,随着类的加载而加载)
静态方法中不能使用this关键字,this代表当前对象调用,静态只能使用类名来调用
静态代码块
格式:
public class 类名称 {
static {
// 静态代码块内容
}
}
特点: 当第一次用到本类时,静态代码块执行唯一一次
静态代码块比非静态的先执行
用途: 用来对一次性的静态成员变量赋值(JDBC)
2. 继承extends
概述
继承主要解决的问题就是: 共性抽取(抽取重复的内容)
1. 继承是多态的前提,没有继承就没有多态
2. 父类(基类/超类)有多少内容,子类(派生类)中就有多少内容
3. 子类可以拥有自己独有的内容
4. 在继承关系中"子类就是一个父类"
使用成员变量
1. 在子类中使用super.父类成员变量名,可以调用父类的成员变量
直接通过子类对象访问成员变量:
等号左边是谁,就有优先谁,如果没有向上找(找父类)
间接通过成员方法访问成员变量:
该方法属于谁,就优先使用谁
2. 父类不能使用子类的成员变量和成员方法,因为不知道都有谁继承了自己
区分三种变量之间重名问题(局部变量,成员变量,父类成员变量)
1. 局部变量: 直接写变量名(name)
2. 成员变量: 可以使用this关键字(this.name = name)
3. 父类成员变量: 使用super关键字(super.name = this. name)
继承中方法的重写(覆盖重写)Override
1. 重写(override): 方法名称,参数列表相同
2. 重载(overload): 方法名称相同,参数列表不同
注意事项:
1. 必须保证父类和子类的方法名和参数列表相同
2. 可以在方法上面写注解: @Override可以起到安全检测
3. 没有注解@Override也是重新,只是起到一个安全检测
4. 子类方法的返回值必须小于,等于父类的返回值范围
5. 子类的方法权限修饰必须大于等于,父类方法的权限修饰符
特征
1. java中继承是单继承,一个类中的父类只能有一个
2. 可以多级继承
3. 一个子类的直接父类是唯一的,但一个父类可以有多个子类
3. 抽象类
抽象方法所在的类必须是一个抽象类,一个抽象类中不一定有抽象方法
概念
1. 对一类事物无法进行精确描述时使用抽象类
2. 抽象类比须使用abstract关键字进行修饰,格式:
public abstract class Hello{
// 定义抽象方法
public abstract void eat();
}
抽象类和方法的使用
1. 不能直接创建抽象类对象
2. 抽象类中可以有构造方法,是提供给子类创建对象时,初始化父类成员使用
3. 抽象类必须使用子类继承,实现抽象类中的所有抽象方法
4. 使用子类对象,进行使用
4. 接口
概述
1. 接口就是多个类的一种公共的规范标准,只要符合规范,就可以通用
2. 接口是引用类型,最重要的内容就是其中的,抽象方法
定义的基本格式
public interface 接口名称 {
// 接口内容
}
注意: 换成了关键字interface后,编译生成的字节码文件仍然是: .java --> .class
接口中可以包含的内容
1. 常量: 使用static final进行修饰,不能改变的量,必须进行赋值,常量名称使用大写,字母之间使用下划线(_)分隔
2. 抽象方法: 子类对象进行调用
3. 默认方法: 用于接口升级,使用默认方法,实现的子类不会报错,如果有多个重名默认方法,就必须重写该方法
4. 静态方法: 不能通过接口实现类的对象来调用接口中的静态方法,可以通过,接口名.静态方法名(参数)进行调用
5. 私有方法: 抽取接口中的公共代码,提供给接口内的默认方法使用
接口之间的多继承
1. 类与类之间是单继承,
2. 类与接口之间是多实现的(一个类可以实现多个接口)
3. 接口与接口之间是多继承的
注意:
1. 多个父接口中的抽象方法重复,没关系
2. 多个父接口中的默认方法重复,需要在子接口类中,重写父接口中的默认方法
5. 多态
概述
1. 继承或者接口的实现,是多态的前提
2. 多态是指对象的多种形态,对象有多种形态
格式
1. 代码当中的多态性: 父类引用指向子类对象
格式:
父类名称 对象名 = new 子类名称();
接口名称 对象名 = new 实现类名称();
访问成员方法和成员变量
1. 在多态代码中,成员方法的访问规则是: 看new的是谁,就优先用谁,没有则向上找
2. 成员方法: 编译看左边,运行看右边
3. 成员变量: 编译看左边,运行看左边
使用多态的好处
1. 好处: 无论右边new的是哪个子类对象,等号左边调用方法都不会变化
向上转型
1. 对象的向上转型,父类对象指向子类对象,其实就是多态写法:
格式: 父类名称 对象名 = new 子类名称();
含义: 右侧创建一个子类对象,把它当作父类来看待使用
注意: 向上转型一定是安全的,类似于基本类型的,小范围向更大范围转换
弊端: 对象一旦向上转型为父类,那么就无法调用子类的原本特有内容
解决方案: 向下转型
向下转型
1. 对象的向下转型,是一个还原的动作:
格式: 子类名称 对象名 = (子类名称)父类对象;
含义: 将父类对象,还原成本来的子类对象
注意: 必须保证对象本来创建的时候就是猫,才能向下转型为猫
如果对象创建的时候本来不是猫,非要向下转型为猫,就会报错
Animal animal = new Cat();
Cat cat = (Cat)animal;
还原后就可以调用子类特有的方法了
类似于基本类型的强制转换
instanceof关键字
1. 格式: 对象 instanceof 类名称
这将会返回一个boolean值结果,也就是判断: 前面的对象能不能当做后面类型的实例
6. final
概述
1. fanal关键字代表最终的,不可改变的
常见用法:
1. 可以用来修饰一个类
2. 可以用来修饰一个方法
3. 可以用来修饰一个局部变量
4. 可以用来修饰一个成员变量
final修饰一个类
1. 当final关键字用来修饰一个类:
格式:
public final class 类名称 {
// ...
}
含义: 当前这个类不能有任何子类(不能被继承)
注意: 如果一个类是final修饰的,那么其中的所有成员方法都无法覆盖重写(因为没有子类)
final修饰一个方法
1. 当final关键字修饰一个方法时,这个方法就是最终方法,也就是不能被覆盖重写:
格式:
public final 返回值类型 方法名(参数){
// 方法体
}
注意: 对于类和方法来说,abstract关键字和final关键字不能同时使用,因为矛盾
final修饰一个局部变量
1. 一旦使用final修饰局部变量,那么这个变量就不能进行更改,只能赋值唯一一次
2. 对于基本类型来说,不可变说的是,变量当中的数据不能改变
3. 对于引用数据类型来说,不可变说的是,变量当中的存储的地址值不能改变,但可以改变其中内容
final修饰一个成员变量
1. 对于成员变量来说,如果使用final关键字修饰,那么这个变量也是不可变的
2. 由于成员变量具有默认值,所以用了final之后必须手动赋值,因为不再给默认值
3. 对于final的成员变量,要么使用成员赋值,要么通过构造方法赋值,二选一
4. 必须保证类当中的所有重载构造方法,都最终会对final修饰的成员变量赋值
7. 内部类
概念与分类
1. 概念: 一个类中包含另一个类,那么这就是一个内部类
2. 分类:
1. 成员内部类
2. 局部内部类(包含匿名内部类)
成员内部类
1. 成员内部类的定义格式:
修饰符 class 外部类名称{
修饰符 class 成员内部类名称{
// ...
}
}
2. 注意:
成员内部类使用外部类,随意访问;外部类使用成员内部类,需要成员内部类对象
3. 如何使用成员内部类:
间接方式: 在外部类的方法当中,使用内部类;然后main只是调用外部类的方法
调用: 在外部类的方法中new 内部类().内部类方法名();
直接方式:
公式: 类名称 对象 = new 类名称();
外部类名称.内部类名称.对象名 = new 外部类名称().new 内部类名称();
内部类的同名变量访问
1. 局部变量: 就近原则
2. 如果出现了重名变量,那么格式是: 外部类名称.this.外部类成员变量名
局部内部类定义
1. 如果一个类是定义在一个方法内部的,那么这就是一个局部内部类
2. 局部内部类,只有当前所属的方法才能使用它,出了这个方法外面就不能用了
定义格式:
修饰符 class 外部类名称 {
修饰符 返回值类型 外部类方法名称(参数列表) {
class 局部内部类名称 {
// 方法体
}
}
}
注意: 局部内部类不能使用任何权限修饰符,没写不是代表默认修饰,是什么都不写
局部内部类final修饰
1. 局部内部类: 如果希望访问所在方法的局部变量,那么这个局部变量必须是,有效final的
2. 从java8+开始,只要局部变量不变,那么fianl关键字可以省略不写
3. 原因:
new出来的对象是在堆内存中
局部变量是跟着方法走的,在栈内存中
方法运行结束后,立即出栈,局部变量就会立即消失
new出来的对象会在堆内存当中持续存在,知道垃圾回收消失
匿名内部类
1. 如果是一个接口的实现类,或者是父类的子类,只需要使用唯一的一次,那么这种情况就可以省略该类的定义,而改为使用,匿名内部类
匿名内部类定义格式:
接口名称 对象名 = new 接口名称() {
// 覆盖重写所有抽象方法
}
注意:
1. 匿名内部类,在创建对象的时候,只能使用唯一一次,如果希望多次创建对象,而且类的内容一样,那么就需要使用单独定义的实现类了
2. 匿名对象,在调用方法时,只能调用唯一一次,如果希望同一个对象调用多次方法,那么必须给对象一个名字,再通过对象名进行调用
3. 匿名内部类是省略了,实现类/子类,但是匿名对象,是省略了对象名
8. Object类
概述
1. java.lang.Object类是Java语言中的根类,及所有类的父类;Object类中描述的方法所有子类都可以使用;在对象实例化的时候,最终找的父类就是Object类
2. 如果一个类没有特别指定父类,那么默认继承Object类
3. 一个类都会直接或者间接继承Object类
toString方法
1. public String toString();返回该对象的字符串表示
2. Object中的toString方法是,包名+类名+地址值,的方式打印输出的
3. 如果子类需要打印内容,可以直接调用toString方法,不用写.toString,因为是默认调用toString方法的
4. 如果没有重写toString方法,直接打印这个类的对应对象名,打印出来的应该是地址值,如果重写了toString方法,则按照重写的方法打印