java final、抽象类、接口

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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值