final
final是一个关键字,可以用于修饰类,成员变量,成员方法。
final修饰基本数据类型,值不能变,final修饰引用数据类型,地址不能改变,但是对象中的属性可以改变
- final修饰的类无法被继承。
- final修饰的方法无法被子类重写。private修饰的方法也是无法被子类重写的,子类是看不到父类的私有方法的。
- final修饰的局部变量,一旦赋值,不可再改变。
- final修饰的成员变量必须初始化值,是一个常量.一般被final修饰的常量的名称的所有字母大写,规范。
- final修饰的引用类型不可以再重新指向其他的java对象。但是fianl修饰的引用,该引用指向的对象的属性值是可以修改的。
final class FinalTest {
//final int m; 报错,final修饰的成员变量定义的时候要初始化,且不能修改,这就是常量了,一般用大写字母
//final 一般和static连用
final static int i =10;//没错,但不规范
final static double PI=3.1415926;
//FinalTest类的构造方法
public FinalTest() {
// this.i=j; //final修饰的成员变量必须在定义的时候显式初始化,不能再修改
}
public static void main(String[] args) {
final int k;
k=20;
System.out.println(k);
//k=30;//final修饰的局部变量,赋值后不能再改变。
System.out.println(k);
B b1=new C();//自动类型转换,向上转型
if (b1 instanceof C) {
C b2=(C)b1;//向下转型,强转
b2.test2();
}
}
}
/*
class A extends FinalTest{
}
//报错,final类无法被继承
*/
class B{
final static int I=15;
public final void test1() {
System.out.println("class B中的test1方法,测试final方法是否可以被重写");
}
}
class C extends B{
public void test2() {
System.out.println(I);//final修饰的成员变量可以被子类调用
}
//public final void test1() {} //报错,不可以重写final修饰的父类成员方法
}
out:
20
20
15
class B{
String name;
int age;
//final修饰的常量
final static int I=15;
}
class C extends B{
public C(String name,int age) {
this.name=name;
this.age=age;
}
public void test2() {
System.out.println(I);//final修饰的成员变量可以被子类调用
}
//public final void test1() {} //报错,不可以重写final修饰的父类成员方法
}
final class FinalTest {
public static void main(String[] args) {
final C c1=new C("Liu",8);
//c1=new C("Zhang",9); 报错,final修饰的引用类型的地址不能变,不能再指向新的对象
c1.name="Lin";
c1.age=15;
System.out.println(c1.name);
System.out.println(c1.age);
}
}
out;
Lin
15
抽象类
定义对象需要用来类描述,但并不是所有类都用来描述对象,有一种类叫做抽象类,里面可能没有具体的代码,无法来描绘一个具体的对象。抽象类定义的目的时为了让子类重写它的抽象方法,所以抽象类可以被继承.
抽象类和抽象方法要用abstract修饰
抽象类的特点:
- 抽象类无法被实例化,无法创建抽象类的对象。抽象类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
- 虽然抽象类不能实例化,但是抽象类也有构造方法,该构造方法是给子类创建对象用的。这也算是多态的一种。
- 抽象类中不一定有抽象方法,但抽象方法必须出现在抽象类中。
- 抽象类中的子类可以是抽象类,如果不是抽象类的话必须对抽象类中的抽象方法进行重写。
- 抽象类和抽象方法不能被final修饰,因为final修饰的类不能被继承.
public abstract class AbstractTest {
int age;
String name;
public AbstractTest() {
System.out.println("抽象类AbstractTest中的构造方法");
}
//抽象类的抽象方法test1和test2,抽象类中可以不定义抽象方法,但是抽象方法如果要定义,必须在抽象类中
public abstract void test1() ;//抽象方法定义时不能有方法体,即大括号{}.
public abstract void test2();
public void test3() {
System.out.println("抽象类中的非抽象方法test3");
}
public static void main(String[] args) {
//AbstractTest at=new AbstractTest();报错,抽象类不能被实例化
A a1=new A("Li",12);//打印出了"抽象类AbstractTest中的构造方法",说明调用了父类的构造方法
AbstractTest b1=new A("Zhang",15);//多态,父类引用指向子类对象,运行时可以调用子类重写过的父类的方法
b1.test1();
b1.test3();
}
}
class A extends AbstractTest{
public A(String name,int age) {
super();//可以调用父类的无参构造方法
this.name=name;
this.age=age;
}
//类A是抽象类的子类,但A不是抽象类,必须要重写抽象类的抽象方法
public void test1() {
System.out.println("重写的抽象父类AbstractTest的test1方法");
}
public void test2() {
System.out.println("重写的抽象父类AbstractTest的test2方法");
}
}
out:
抽象类AbstractTest中的构造方法
抽象类AbstractTest中的构造方法
重写的抽象父类AbstractTest的test1方法
抽象类中的非抽象方法test3
接口interface
类用来描述对象的方法和属性,接口 包含类要实现的方法,接口的存在时为了定义一个规范,为了让实现接口的类重写接口中所有的抽象方法,否则就要声明为抽象类.
接口和类相似的地方在于,一个接口中可以有多个方法,同样保存在.java文件中,文件名用接口名,编译后的字节码文件保存在.class文件中。
接口特点:
- 接口中只能出现常量(public static final)和抽象方法(抽象方法就是只定义方法,没有方法体(大括号"{}"叫方法体))
- 接口里面没有构造方法,无法被实例化,即无法创建接口对象
- 接口和接口之间支持多继承,即一个接口可以有多个父接口,使用extends关键字,不同接口之间用逗号","隔开
- 一个类可以实现多个接口,即一个类可以有多个父接口,使用implements关键字,不同接口之间用逗号","隔开
- 一个类如果实现了接口,那么这个类需要重写接口中所有的抽象方法(建议),如果不重写则这个类需要声明为抽象类(不建议)
另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
例子:
interface InterfaceTest {
public final static double PI=3.1415926;
// public final static 可以省略,如果省略,变量会被隐式的指定为 public static final 变量
//并且只能是 public,用 private 修饰会报错
int I=9;
//接口中的方法只能是抽象方法,并且用public abstract修饰,
//接口中每一个方法也是隐式抽象的,public abstract可以省略,如果省略的话,接口中的方法会被隐式的指定为 public abstract
//只能是 public abstract,其他修饰符都会报错
public abstract void test1();//抽象方法不能有方法体
public abstract void test2();
//private abstract void test3();,只能时public abstract修饰,否则报错
void test4();//public abstract可以省略,隐式指定为public abstract修饰
}
interface A1{
public abstract void testA1() ;
}
interface B{
void testB1();
}
//接口的继承,使用extends关键字,可以多继承
interface C extends InterfaceTest,A1{
void testC1();
}
//抽象类实现接口,可以重写接口的方法,也可以不写,或者写一部分
abstract class E implements A1,B{
//只重写了接口A1的方法,没重写接口B的方法,也可以一个不写
public void testA1() {}
}
//接口的实现,使用implements关键字,可以实现多个接口, 实现接口的类要重写接口的全部方法.
class D implements InterfaceTest,A1{
//重写了接口InterfaceTest,A1的全部方法
public void test1() {}
public void test2() {}
public void test4() {}
public void testA1() { }
}
抽象类和接口的区别:
1抽象类的成员变量没有限制,接口中的成员变量只能是被public final abstract修饰,(虽然可以省略这些词,但系统还是会默认这样修饰)
2抽象类中可以有成员方法和抽象方法(没有方法体),但接口中只能有抽象方法,不能有成员方法.成员方法有方法体,可实现某些功能
3抽象类可以有静态代码块和静态方法,接口中不能有.
4一个类只能继承一个抽象类,但可以实现多个接口.
在多态中的小例子
//接口MediaPlayer
public interface MediaPlayer {
public abstract void playvideo();
}
//类Laptop实现了接口
class Laptop implements MediaPlayer{
public void playvideo() {
System.out.println("the notebook is playing video about game");
}
}
//类Mobile也实现了接口
class Mobile implements MediaPlayer{
public void playvideo() {
System.out.println(" the mobile phone is playing movie about Modern life");
}
}
//类Person调用了接口MediaPlayer被实现后重写的方法
public class Person {
public void watch(MediaPlayer m) {
m.playvideo();
}
}
//测试类
public class InterfacePolymorphicTest {
public static void main(String[] args) {
Person p=new Person();
//MediaPlayer 是一个接口,这里是多态的体现,编译过程,首先向上转型,静态绑定m1的引用为MediaPlayer,
//执行过程,调用到m1的方法时,动态绑定,指向堆内存中的对象方法,即重写的接口方法
MediaPlayer m1=new Laptop();
p.watch(m1);
MediaPlayer m2=new Mobile();
p.watch(m2);
}
}
out:
the notebook is playing video about game
the mobile phone is playing movie about Modern life
参考:http://www.monkey1024.com/javase/314
参考:http://www.runoob.com/java/java-interfaces.html