初学java的人,可以来看看这些关键字的用法和注意事项
多态 ---
相同的消息发给不同的对象,得到的是不同的结果。
让代码书写更简短父类的引用指向子类的对象
1.编译器绑定
2.运行时绑定
3.只有实例方法存在重写,多态4.多态的强制类型转换
--向下转型,从大到小,不能直接转,所以需要强转,而强转发生在线性继承关系的父子类中
Animial animial=new Dog();
--错误示例:Cat cat=(Cat)animial;
--正确示例:需要 instanceof 比较运算符
if (animial instanceof Cat) {
cat=(Cat)animial;
System.out.println("将animial转成cat");
}
else if (animial instanceof Dog) {
dog=(Dog)animial;
System.out.println("将animial转成dog");
}
结果输出:将animial转成dog
static 修饰符变量:静态的,被static修饰的成员存储位置不同,不在堆里,被全类所共有的,不单独属于某个对象
可以被对象访问,但是通常用 类名. 的方式来访问
static修饰全局变量,无法修饰局部变量
修饰方法: public static void func(){}
可以直接被static修饰的main方法访问,同时静态方法可以直接访问静态变量,只能访问静态的方法,不能访问实例的变量和方法
实例的可以访问所有的变量和方法
被static修饰的方法无法被重写
修饰块{} 块------>{}
静态块--> static {} 通常用来给静态变量赋值(且只能给静态的变量赋值) 在类被加载时执行,且执行一次。
静态块优先于构造器执行
final
final 修饰的变量:一旦被赋值,则值可用却不可变 final
修饰局部变量时,可以不用赋值,但是使用时,必须赋值 final
修饰成员变量时,必须赋初值:可以在声明的时候直接赋值(赋值后无法在构造时重新赋值),也可以声明的时候不赋值,在构造时赋值 final
修饰对象时,对象的地址不可变,但对象本身的属性并非final的,所以可以变。哪怕将final对象赋值为null也不行
修饰静态成员,可以直接賦值,也可以在静态块中赋值(不建议),不能在构造器中赋值。
修飾方法,只要可见,子类可以使用父类的final方法,但子类不可以重写(覆盖)父类的final方法
修饰类:被final修饰的类不能被继承,但可以继承别人 (String类是final的)
有关static和final的代码:
class A {
int i;
public void f() {
System.out.println("这是父类的f方法");
}
public final void m(){
System.out.println("这是父类最终的方法m");
}
}
class B extends A{
public void f() {
System.out.println("对父类的方法进行重写");
}
}
public class Demo1 {
public static final int MAME = 10;
public static final int MAMEQ;
final int k = 10;
final int k1;
int i;
static int y;
static {
// Err:i=10;
MAMEQ = 20;
y = 10;
System.out.println("静态块执行");
}
Demo1() {
k1 = 20;
// Err : MAMEQ=20;
System.out.println("構造器、、、、");
}
public static void main(String[] args) {
final int i;
System.out.println("第二輸出、、、、");
new Demo1();
new Demo1();
new Demo1();
A a = new A();
a.i = 10;
final A a1 = new A();
a1.i = 10;
// Err a1=new A();
B b=new B();
b.f();
b.m();//子类b使用父类的final方法
}
}
abstract
abstract修饰的类叫做抽象类,他是个不完整的东西 它可以有构造,但是不能通过构造创建抽象对象 他可以创建自己的子类的对象(多态)
抽象方法是不完整的方法,他没有具体的实现,专门用来被重写的
final与abstract不可共存
抽象类不一定有抽象方法,但只有抽象类才能产生抽象方法
1.如果子类继承抽象类,而抽象类中有一个抽象方法,则子类必须重写抽象方法,普通方法则没有强制要求
2.如果子类不想重写父类的抽象方法,则将子类也定义为抽象类即可
抽象类中可以有实例方法,但接口中的方法全是抽象的
抽象类中写的抽象方法必须要加abstract关键字,并没有默认为是public访问权限
配合着abstract注释看代码:
public class Demo2 {
public static void main(String[] args) {
B1 b=new C();
b.f();
b.m();
}
}
class A1 {
}
abstract class B1 {
//完整的方法
void f() {
System.out.println("這是一個完整的方法,但包含我的类是不完整的");
}
//不完整的方法
abstract void m();
}
class C extends B1 {
void f() {
System.out.println("000000000000000");
}
@Override
void m() {
System.out.println("这是子类对父类抽象方法的覆盖");
}
}
interface
接口的定义:
接口声明的关键字:interface
接口当中的方法:默认是public abstract修饰的,即使不写,也是这样的
接口中也可以有变量,但这个变量实际上是 public static final的常量,但我们一般不在接口中定义常量
而接口中的方法是共有的,全是abstract的,写不写都一样 抽象类中有构造,接口总不存在构造
接口的多继承:接口继承接口,关键字是extends,接口可以继承多个接口,被继承的多个接口与之间用 “,” 隔开
类可以继承一个(只能一个)类并且实现多个接口(继承在前,实现在后),关键字是:implements,被实现的多个接口之间用“,”隔开
// 接口C1
interface C1 {
void f();
}
// 类CIm实实现接口C1
class CIm implements C1 {
@Override
public void f() {
System.out.println("CIm--f");
}
public void ff() {
System.out.println("CIm--ff");
}
}
// 抽象类实现接口C1
abstract class CIm2 implements C1 {
public void m() {
System.out.println("CIm2--m");
}
}
// 类D继承抽象类CIm2,冲写了了f(),m()方法
class D extends CIm2 {
@Override
public void f() {
System.out.println("D--f");
}
public void m() {
System.out.println("D--m");
}
}
public class Demo3 {
public static void main(String[] args) {
// c1只能调用--实现了接口并且重写了接口中方法的--方法
C1 c1 = new CIm();
c1.f();
// CIm cIm=null;
// if (cIm instanceof CIm) {
// cIm=(CIm)c1;
// }
// cIm.ff();
((CIm) c1).f();
((CIm) c1).ff();
CIm2 cIm2 = new D();
c1 = cIm2;// 接口指向了类D,并调用了D中的方法
c1.f();
((D) c1).m();
}
}