目录
修饰符
1、static修饰符
2、final修饰符
3、abstract修饰符
接口
1、接口的本质
2、接口与抽象类的区别
3、接口中的方法都是抽象方法
4、接口中的变量都是静态常量(public static final修饰)
5、一个类可以实现多个接口
6、一个接口可以继承多个父接口
7、接口的作用
1、static变量
在类中,使用static修饰的成员变量,就是静态变量,反之为非静态变量。
静态变量和非静态变量的区别
静态变量属于类的,"可以"使用类名来访问,非静态变量是属于对象的,"必须"使用对象来访问.
public class Student{ private static int age; private double score; public static void main(String[] args) { Student s = new Student(); //推荐使用类名访问静态成员 System.out.println(Student.age); System.out.println(s.age); System.out.println(s.score); } } 点击并拖拽以移动 public class Student{ private static int count; private int num; public Student() { count++; num++; } public static void main(String[] args) { Student s1 = new Student(); Student s2 = new Student(); Student s3 = new Student(); Student s4 = new Student(); //因为还是在类中,所以可以直接访问私有属性 System.out.println(s1.num); System.out.println(s2.num); System.out.println(s3.num); System.out.println(s4.num); System.out.println(Student.count); System.out.println(s1.count); System.out.println(s2.count); System.out.println(s3.count); System.out.println(s4.count); } }
在加载类的过程中为静态变量分配内存,实例变量在创建对象时分配内存,所以静态变量可以使用类名来直接访问,而不需要使用对象来访问.
2、static方法
在类中,使用static修饰的成员方法,就是静态方法,反之为非静态方法。
静态方法和非静态方法的区别
静态方法数属于类的,"可以"使用类名来调用,非静态方1 法是属于对象的,"必须"使用对象来调用.
注意:this和super在类中属于非静态的变量.(静态方法中不能使用)
public class Student{ private static int count; private int num; public void run(){} public static void go(){} public static void test(){ //编译通过 System.out.println(count); go(); //编译报错 System.out.println(num); run(); } }
3、代码块和静态代码块
类中可以编写代码块和静态代码块
public class Person { { //代码块(匿名代码块) } static{ //静态代码块 } }
匿名代码块和静态代码块的作用
匿名代码块的作用是给对象的成员变量初始化赋值,但是因为构造器也能完成这项工作,所以匿名代码块使用的并不多。
静态代码块的作用是给类中的静态成员变量初始化赋值。
例如:
public class Person { public static String name; static{ name = "tom"; } public Person(){ name = "bob"; } } main: System.out.println(Person.name);//bob结果为
4、创建和初始化对象的过程
Student s = new Student();
Student类之前没有进行类加载
1. 类加载,同时初始化类中静态的属性
2. 执行静态代码块
3. 分配内存空间,同时初始化非静态的属性(赋默认值,0/false/null)
4. 调用Student的父类构造器
5. 对Student中的属性进行显示赋值(如果有的话)
6. 执行匿名代码块
7. 执行构造器
8. 返回内存地址
5、静态导入
静态导包就是java包的静态导入,用import static代替import静态导入包是JDK1.5中的新特性。意思是导入这个类里的静态方法。
好处:这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。
但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便。
1、修饰类
用final修饰的类不能被继承,没有子类。
例如:我们是无法写一个类去继承String类,然后对String类型扩展的,因为API中已经被String类定义为final的了.
定义final修饰的类:
public final class Action{ } //编译报错 public class Go extends Action{ }
2、修饰方法
用final修饰的方法可以被继承,但是不能被子类的重写。
定义final修饰的方法:
public class Person{ public final void print(){} } //编译报错 public class Student extends Person{ public void print(){ } }
3、修饰变量
用final修饰的变量表示常量,只能被赋一次值.其实使用final修饰的变量也就成了常量了,因为值不会再变了。
修饰局部变量:
public class Person{ public void print(final int a){ //编译报错,不能再次赋值,传参的时候已经赋过了 a = 1; } } public class Person{ public void print(){ final int a; a = 1; //编译报错,不能再次赋值 a = 2; } }
修饰成员变量-非静态成员变量:
public class Person{ private final int a; }
只有一次机会,可以给此变量a赋值的位置: 声明的同时赋值 匿名代码块中赋值 构造器中赋值(类中出现的所有构造器都要写)
修饰成员变量-静态成员变量:
public class Person{ private static final int a; }
只有一次机会,可以给此变量a赋值的位置: 声明的同时赋值 静态代码块中赋值
修饰引用变量:
main: final Student s = new Student(); //编译通过 s.setName("tom"); s.setName("zs"); //编译报错,不能修改引用s指向的内存地址 s = new Student();
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
1、抽象类和抽象方法的关系
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
public abstract class Action{ public abstract void doSomething(); } public void doSomething(){...}
3、特点及作用
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类后,需要实现抽象类中没有实现的抽象方法,否则这个子类也要声明为抽象类。
public abstract class Action{ public abstract void doSomething(); } main: //编译报错,抽象类不能new对象 Action a = new Action(); //子类继承抽象类 public class Eat extends Action{ //实现父类中没有实现的抽象方法 public void doSomething(){ //code } } main: Action a = new Eat(); a.doSomething();
注意:子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法) 都有!
接口:只有规范!
抽象类也是类,除了可以写抽象方法以及不能直接new对象之外,其他的和普通类没有什么不一样的。接口已经另一种类型了,和类是有本质的区别的,所以不能用类的标准去衡量接口。
声明类的关键字是class,声明接口的关键字是interface。
抽象类是用来被继承的,java中的类是单继承。
类A继承了抽象类B,那么类A的对象就属于B类型了,可以使用多态
一个父类的引用,可以指向这个父类的任意子类对象
继承的关键字是extends
接口是用来被类实现的,java中的接口可以被多实现。
类A实现接口B、C、D、E..,那么类A的对象就属于B、C、D、E等类型了,可以使用多态
一个接口的引用,可以指向这个接口的任意实现类对象
实现的关键字是implements
接口中可以不写任何方法,但如果写方法了,该方法必须是抽象方法
public interface Action{ public abstract void run(); //默认就是public abstract修饰的 void test(); public void go(); }
接口中可以不写任何属性,但如果写属性了,该属性必须是public static final修饰的静态常量。
可以直接使用接口名访问其属性。因为是public static修饰的
声明的同时就必须赋值.(因为接口中不能编写静态代码块)
public interface Action{ public static final String NAME = "kou"; //默认就是public static final修饰的 int AGE = 100; } main: System.out.println(Action.NAME); System.out.println(Action.AGE);
public class Student implements A,B,C,D{ //Student需要实现接口A B C D中所有的抽象方法 //否则Student类就要声明为抽象类,因为有抽象方法没实现 } main: A s1 = new Student(); B s2 = new Student(); C s3 = new Student(); D s4 = new Student();
s1只能调用接口A中声明的方法以及Object中的方法
s2只能调用接口B中声明的方法以及Object中的方法
s3只能调用接口C中声明的方法以及Object中的方法
s4只能调用接口D中声明的方法以及Object中的方法
public interface A{ public void testA(); } public interface B{ public void testB(); } //接口C把接口A B中的方法都继承过来了 public interface C extends A,B{ public void testC(); } //Student相当于实现了A B C三个接口,需要实现所有的抽象方法 //Student的对象也就同时属于A类型 B类型 C类型 public class Student implements C{ public viod testA(){} public viod testB(){} public viod testC(){} } main: C o = new Student(); System.out.println(o instanceof A);//true System.out.println(o instanceof B);//true System.out.println(o instanceof C);//true System.out.println(o instanceof Student);//true System.out.println(o instanceof Object);//true System.out.println(o instanceof Teacher);//false //编译报错 System.out.println(o instanceof String);
一个引用所指向的对象,是有可能实现任何一个接口的。(java中的多实现)
接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建
【接口名】 【对象名】= new 【实现接口的类】
这样你像用哪个类的对象就可以new哪个对象了,不需要改原来的代码。
假如我们两个类中都有个function()的方法,如果我用接口,那样我new a();就是用a的方法,newb()就是用b的方法
这个就叫统一访问,因为你实现这个接口的类的方法名相同,但是实现内容不同
总结:
1、Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)
2、Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化
3、Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法
4、接口中没有构造方法,不能被实例化
5、一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口
6、Java接口必须通过类来实现它的抽象方法
7、当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类
8、不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例
9、 一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承