static
概念
1、 是java中的一个关键字
2、 用于修饰成员(成员变量和成员方法)
特点
1、 可以修饰成员变量,成员方法
2、 随着类的加载而加载,优先于对象加载
3、 只加载一次,就会一直存在,不再开辟新空间
4、 全局唯一,全局共享
5、 可以直接被类名调用
6、 静态只能调用静态,非静态可以随意调用
7、 static不能和this或者super共用,因为有static时可能还没有对象
静态调用关系
public class A{
public static void main(String[] args) {
Teacher t = new Teacher();
t.speak();
}
}
class Teacher{
static int age=30;
String name="张三";
//非静态测试
public void speak(){
System.out.println(age);//非静态能调用静态变量
System.out.println(name);//非静态能调用非静态变量
qiao();//非静态能调用静态方法
}
//静态测试
public static void qiao(){
System.out.println(age);//静态能调用静态
// System.out.println(name);//静态不能调用非静态变量,只能调用静态变量
// speak();//静态不能调用非静态方法,只能调用静态方法
}
}
静态、构造、局部代码块
执行顺序:静态代码块—构造代码块—构造函数
静态代码块
随着类的加载而加载,并且只被加载一次,一般用于项目的初始化
static{
…
}
概述
1、 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化
2、 构造代码块:在调用构造方法前会自动调用,每次创建对象都会被调用
3、 局部代码块:方法里的代码块,方法被调用时才会执行
4、 静态代码块:static{ },位置:在类里方法外
5、 TODO创建测试类,类中写好静态代码块,构造代码块,构造方法,普通方法里嵌套局部代码块。测试他们的执行顺序。
6、 静态 - 构造代码块 - 构造方法 - 局部
例:
public class Test{
public static void main(String[] args) {
Car c = new Car();c.show();
Car c2 = new Car();
}
}
class Car{
//静态代码块
//1,在类第一次加载时就加载到内存中并一直驻存,
//并全局共享,直到类消失静态资源才消失
//2,并且静态资源只被加载一次
static {
System.out.println(1);
}
//构造代码块
{
System.out.println(2);
}
// 构造方法
public Car() {
System.out.println(3);
}
public void show() {
// 局部代码块
{
System.out.println(6);
}
System.out.println(4);
System.out.println(5);
}
}
静态变量和实例变量的区别
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用
final
概念
1、 是java提供的一个关键字
2、 final是最终的意思
3、 final可以修饰类,方法,成员变量
初衷是因为:java出现了继承后,子类可以更改父类的功能,当父类功能不许子类改变时可以利用final关键字修饰父类。
特点
1、 被final修饰的类,不能被继承
2、 被final修饰的方法,不能被重写
3、 被final修饰的变量是个常量,值不能被更改
4、 常量的定义形式: final 数据类型 常量名 = 值
多态
概念
多态指同一个实体同时具有多种形式。它是面向对象程序设计(OOP)的一个重要特征。
主要是指同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
好处是可以把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。
例如:水,在不同时刻可以有多种形态,包括水蒸气,冰,水。
Java怎么体现多态呢?
class Animal
class Dog extends Animal
Dog d = new Dog();//狗是狗
Animal a=new Dog();//狗是小动物,创建了狗的对象,赋值给动物对象,这就是多态
特点
1、 多态的前提是继承
2、 要有方法的重写
3、 父类引用指向子类对象,如:Animal a = new Dog(); – 小到大,向上转型
4、 多态中,编译看左边,运行看右边
多态的好处:
1、 多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法。
2、 提高了程序的扩展性和可维护性
多态的使用特点:
1、成员变量:使用的是父类的
2、成员方法:由于存在重写现象所以使用的是子类的
3、静态成员:随着对象而存在,谁调用的就返回谁的
向上转型和向下转型
在JAVA中,继承是一个重要的特征,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。
在应用中就存在着两种转型方式,分别是:向上转型和向下转型。
比如:父类Parent,子类Child
向上转型:父类的引用指向子类对象Parent p=new Child();
说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类的方法就根据这个引用指向调用子类重写方法。
向下转型(较少):子类的引用的指向子类对象,过程中必须要采取到强制转型。
Parent p = new Child();//向上转型,此时,p是Parent类型
Child c = (Child)p;//此时,把Parent类型的p转成小类型Child
//其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的
说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。
异常
概述
用来封装错误信息的对象。
组成结构:类型,提示,行号
异常的继承结构
Throwable - 顶级父类
-- Error:系统错误,无法修复
-- Exception:可修复的错误
--RunTimeException
--ClassCastException
--ClassNotFoundException
异常处理
程序中遇到了异常,通常有两种处理方式:捕获或者向上抛出。
当调用了一个抛出异常的方法时,调用位置可以不做处理继续向上抛出也可以捕获异常。
1、捕获方式:
try{
需要捕获的代码
}catch(异常类型 异常名){
处理方案
}
2、抛出方式:
在会发生异常的方法上添加代码:throws 异常类型
例如:
public static void main(String[] args) throws Exception{}
例:
//测试异常的发生和解决
public class TestException {
//接收键盘输入的两个整数并做除法运算
public static void main(String[] args) {
//1,捕获异常:把可能发生异常的代码放在try里,
//当异常发生时会被catch住并执行catch中的代码执行异常处理的代码
try {
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a/b);
} catch (Exception e) {
//提出解决方案
System.out.println("您输入的两次整数有误!");
}
}
}
访问控制符
用来控制一个类,或者类中的成员的访问范围。
抽象类
概念
Java中可以定义没有方法体的方法,该方法由其子类来具体的实现。该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。
抽象类可以理解为是一个只有方法声明没有方法体的特殊类。
特点
1、 通过java关键字abstract实现
2、 可以修饰方法或者类
3、 抽象类中可以没有抽象方法(由子类去实现)
4、 如果类中有抽象方法,那该类必须定义为一个抽象类
5、 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写
6、 多用于多态中
7、 抽象类不可以被实例化
抽象类的用法
构造函数
抽象类也有构造方法,但是不能本身实例化。 那抽象类的构造函数有啥用?一般用于给子类实例化。
//抽象类的构造方法
public class Test_Animal {
}
abstract class Animal{
//抽象类可以有构造方法,但是无法实例化
//用于子类实例化
public Animal2(){
System.out.println("fu..Animal2()");
}
}
class Zi extends Animal{
}
class TestAnimal{
public static void main(String[] args) {
// Animal2 a = new Animal();//抽象类无法实例化
// Zi z=new Zi();//创建子类实例化对象
Animal a2 = new Zi();//抽象类多用于多态
}
}
抽象类的成员变量
抽象类既可以有变量,也可以有常量
抽象类的成员方法
抽象类里,既可以有普通方法,有可以有抽象方法
接口
概念
Java里面由于不允许多重继承,所以如果要实现多个类的功能,则可以通过实现多个接口来实现。
Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层。
interface 接口名{ 代码… }
特点
1、 接口中都是抽象方法
2、 通过interface关键字创建接口
3、 通过implements让子类来实现
4、可以理解成,接口是一个特殊的抽象类
5、 接口突破了java的单继承的局限性
6、 接口和类之间可以多实现,接口和接口之间可以多继承
7、接口是对外暴露的规则,是一套开发规范
8、 接口提高了程序的功能扩展,降低了耦合性
例:
public class T {
public static void main(String[] args) {
Zi z = new Zi();
z.study();
z.teach();
}
}
interface Fu{
public abstract void study();
public abstract void teach();
}
//实现+重写
class Zi implements Fu{
public void study(){
System.out.println("Zi..study()");
}
public void teach(){
System.out.println("Zi..teach()");
}
}
接口的用法
构造方法
接口里是没有构造方法的。
在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。
interface Fu{//定义一个接口
public abstract void show();
//Interfaces cannot have constructors
/*public Fu(){
System.out.println("Fu.Fu()");
}*/
}
成员变量
接口里没有成员变量,都是常量。所以,你定义一个变量没有写修饰符时,默认会加上: public static final
接口的成员方法
接口里的方法,默认就都是抽象的,如果你不写明是abstract的,那会自动补齐。
例如:public abstract void save
接口的复杂用法
Java中单继承的局限性通过接口可以解决。
接口可以多继承也可以多实现,甚至可以继承的同时多实现。
例:
//这个类用来测试接口的复杂用法:多继承多实现
public class Test4_ComInter {
public static void main(String[] args) {
Interface1 in = new Interface1Impl();
in.save();
in.update();
}
}
//创建接口1
interface Interface1{
void save();
void update();
}
//创建接口2
interface Interface2{
void get();
void delete();
}
//1、打破了java单继承的局限性,因为接口之间可以多继承,多个接口之间逗号隔开
interface Interface3 extends Interface1,Interface2{
void add();
}
//3、接口还可以多实现吗??---可以多实现,只不过接口之间逗号隔开
class ManyImpl implements Interface1,Interface2{
public void save() {}
public void update() {}
public void get() {}
public void delete() {}
}
//4、接口可以继承的同时,多实现?? --
class MoreImple extends ManyImpl implements Interface1,Interface2 {
}
//2、创建实现类,使用3号接口的功能,需要重写几个方法呢??---同时重写1号和2号和3号接口里的所有功能
class Interface3Impl implements Interface3{
@Override
public void save() { }
@Override
public void update() { }
@Override
public void get() { }
@Override
public void delete() { }
@Override
public void add() { }
}
//TODO 创建实现类
class Interface1Impl implements Interface1{
@Override
public void save() {
System.out.println("save()...");
}
@Override
public void update() {
System.out.println("update()...");
}
}
总结
类和类的关系:
继承 extends / 单继承 / 单根继承
– 继承的意义:为了提高代码的复用性,减少了代码的编写提高开发效率。
– 方法重写的意义:在不修改父类源码的前提下,在子类中重写业务,从此使用的就是重写后的功能。
– 要求子类的方法声明和父类一样,只要改方法体。
– 有了继承有了重写就产生了多态,多态的意义:为了统一程序的调用标准,标准就是父类。
– 多态 也就是向上转型/向上造型。
– 向下造型的意义:很少用,相当于想要使用子类的特殊功能,还不如直接创建子类对象简单。
– class A extends B
– 其中,A和B都是类,A是子类,B是父类,A就拥有了B的所有功能(除了私有的和构造方法)
– 其他知识点:this 和super ,构造方法,各种代码块…
类和接口关系:
实现implements / 单实现 / 多实现
– class A implements B,C
– 其中,A是实现类,B和C是接口
– 要求A 可以把 B 和C 接口里的所有 抽象方法 都重写掉,否则 A 就是抽象类
– 接口不能创建对象
– 接口里没有构造方法,接口里都是常量,接口里都是抽象方法
接口和接口关系:
继承extends / 单继承 / 多继承
– 接口的多继承的关系,打破了java单继承的局限性
– interface A extends B,C
– 其中,A B C 都是接口,A是子接口,同时拥有B和C接口里的所有功能
– class AImpl implements A
– 要求AImpl需要重写A接口里的所有方法(是包含B和C接口的所有方法),否则就是抽象类
接口和抽象类的区别
– 相同点:都是抽象层,都不能实例化
– 不同点:
– 1、抽象类用abstract关键字描述,接口用interface
– 2、子类和抽象类之间是extends关系,实现类和接口之间是implements关系
– 3、抽象类中 可以 有构造方法 ,接口里 不能 出现 构造方法
– 4、抽象类里可以有 变量,接口里没有变量全都是静态的常量
– 5、接口里定义常量的语法:public static final String NAME=“jack”,会为变量自动拼接public static final
– 6、抽象类里 可以有普通方法 也可以有 抽象方法,接口都是抽象方法
– 7、抽象类和子类之间是继承关系,而且java中,只支持单继承
– 8、接口突破了java单继承的局限性,因为接口可以多继承也可以多实现,甚至可以继承的同时多实现
– 9、接口的复杂用法
– 多继承: interface A extends B,C 其中A是子接口,同时拥有自己的和BC的功能
– 多实现: class AImpl implements M,N,O,P 其中AImpl是实现类,需要同时重写MNOP的所有抽象方法,否则就是一个抽象类
– 继承的同时多实现: class AImpl extends Object implements M,N 一定是先继承后实现