四种类型编译之后都是class文件。
一、类
1、基础知识
①修饰符:
final(最终,不可修改),static(静态),权限修饰符(public,protected,友好,protected),abstract(抽象类)
②变量
按作用域分类:全局变量,局部变量
按初始化时机分类:实例变量,静态变量,常量(引用数据类型可以修改其属性),
③方法
定义:[修饰符列表] 返回值 方法名 形参列表
分类:根据修饰符的不同可以分为:静态,实例,抽象,
特殊:静态代码块,主方法,构造方法
用法:重载(方法名相同,形参列表不同,与修饰符/返回值无关),递归(自己调用自己:堆栈溢出异常),重写(方法名相同,形参列表相同,权限必须提高,不能抛出更大的异常,返回值必须是子类获取实现)
2、三大特征:封装,继承,多态
①封装:属性私有化
只能在本类中才允许直接通过属性修改值,其他类必须通过公共的public方法修改值或者调用,这样在方法中就能够判断其他类的值是否在允许范围内。避免其他类随意修改本类中的属性值(通过使用set/get方法进行操作)
②继承:子类继承父类中所有的非构造方法和属性,java不支持多继承,但是可以用利用接口间接实现多继承。子类不能重写父类的私有方法
子类继承父类中的方法,还可以重写父类的方法,对于静态方法,只是子类调用了父类的静态方法,如果子类重写静态方法(符合重写规则),那么才是访问自己的静态类(类加载)。
子类构造方法,默认就会加上super()方法,调用父类的无参构造方法,加载父类的属性和方法,然后在创建实例对象。
②多态:一种方法的不同表示形态,比如所有动物都有进食的行为,但是老虎食肉动物,长颈鹿是食草动物
java中对于存在实现关系或者继承关系的类可以使用多态,子类重写方法就可以体现方法的多种形态。
public class Person {
private String nation;
public Person(String nation){this.nation=nation;}
public String getNation() {
return this.nation;
}
public void setNation(String nation) {
this.nation = nation;
}
}
public class American extends Person {
public American(String nation) {
super(nation);//国籍属性是在父类中共有的,因为封装的特点,所以调用父类构造方法初始化
}
}
public class Chinese extends Person {
public Chinese(String nation) {
super(nation);//国籍属性是在父类中共有的,因为封装的特点,所以调用父类构造方法初始化
}
}
Person american = new American("美国人");
Person chinese = new Chinese("中国人");
System.out.println(american.getNation());//子类继承父类的公共方法,然后调用父类的私有属性
System.out.println(chinese.getNation());//子类继承父类的公共方法,然后调用父类的私有属性
接口引用实现类的对象,就是向上转型,向下转型需要引用之前有发生向上转型才可以。
3、抽象类:Abstract修饰(不能与final同时修饰)
类的方法里面含有抽象方法(没有方法体,只有方法的声明)的一定是抽象类,抽象类不一定有抽象方法,抽象类和接口都是无法直接实例化的(匿名内部类可以实现)。
用处:对方法的部分封装,很好的利用了多态的思想,子类是必须实现方法(也就是重写),如果子类也是抽象类,可以不实现。
子类继承抽象类必须实现抽象方法(除非子类也是抽象类)
4、内部类
内部类可以无条件的访问外部类的属性和方法,外部类可以通过创建内部类对象的引用访问内部类的属性和方法,只有当static修饰时,内部类才可以定义静态的方法和属性。也可以使用protecte,private修饰内部类的访问权限。
匿名内部类,使用一个没有类名的匿名类继承或者实现接口,这样可以就可以实例抽象类和接口。
public abstract class A {
public abstract void doSome(String str);
public static void main(String[] args) {
new A() {
public void doSome(String str) {
System.out.println(str);
}
}.doSome("???");
}
}
二、接口
和抽象类类似,但是接口的所有方法都是抽象,即完全抽象。而且属性皆是常量。不能够实例,支持多实现
接口是完全抽象,较抽象类而言(可以有自己的方法),接口只是方法的声明,实现类需要实现所有的抽象方法。
public interface Animal {
void say();
}
public class Tiger implements Animal {
@Override
public void say() {
System.out.println("我是食肉动物");
}
}
public class Panda implements Animal {
@Override
public void say() {
System.out.println("我是食草动物");
}
}
public class Test {
public static void main(String[] args) {
Animal tiger = new Tiger();//向上转型,将tiger的引用是Tiger对象
Animal panda = new Panda();//向上转型,panda的引用时Panda实例对象
panda.say();//编译时,会检查Animal的say是否say方法,运行时调用Panda类的say方法:食草动物
tiger.say();//编译时,会检查Animal的say是否say方法,运行时调用Tiger类的say方法:食肉动物
tiger = (Tiger)tiger;//向下转型
}
}
三、枚举
枚举就是一个普通的java类,通过反编译工具可以发现,其实本身是一个不可以被继承的类(final修饰S),而且他继承了Enum类型,在类体的第一行定义该类型的常量(可通过构造赋值)。应用场景,对于某一个功能,可能会有不同的固定好表达方式,比如季节,只有spring,summer,autumn,winter。星期(1,2,3,4,5,6,0)
public enum MyEnum {
LY("LY"),LHP("LHP"),CJ("CJ"),LCJ("LCJ");
private String name;
MyEnum(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
for (MyEnum e : MyEnum.values()) {//获取枚举类型声明的所有常量
System.out.println(e.ordinal());//相当于我们定义Enum类型常量的时候的一个下标值,从0开始
}
System.out.println(LY.compareTo(LHP));//通过oridinal()比较大小
}
}
四、注解
概念:注解分为元注解和自定义的注解,元注解出现在自定义的注解之上,注解可以用来约束我们的类,接口,变量,方法。。。,用来标注这个成员的含义,信息等等,而元注解就是用来约束和标注自定义注解的。
常用的注解有:
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问,作用域。
@Documented - 标记这些注解是否包含在用户文档中。
@Target - 标记这个注解应该是标注哪种 Java 成员。
@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
作用:
在程序编译或者运行时,我们可用通过Class字节码对象去java成员上的注解,根据注解内容做出动态的改变,可以极大的降低开发难度。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Anno {
Target target();//
int value ();
double d();
}