final关键字
1.final表示最终的不可变的
2.final修饰的变量,方法,类
3.final修饰的类无法继承
4.final修饰的方法无法覆盖
5.final修饰的变量一旦赋值,不能重新赋值
6.final修饰的新对象永远只能指向该对象,并且永远指向该对象,并且该对象不会被垃圾回收器回收,直到该方法结束,不过对象内部的数据可以修改
7.final修饰的实例变量,系统不会赋默认值,必须手动赋值!定义时手动赋值,或者构造方法中赋值,无参的构造方法必须有赋值语句,不会赋默认值
8.实例变量既然用final修饰了,就不会随着对象而变化,所以一般用static修饰,节省堆内存空间
栗子
public class finaltext {
public static void main(String[] args) {
final int i = 100;
//i = 200; 报错,final修饰的无法修改
person p1 = new person(20);
final person p2 = new person(30);
//p2 = new person(30); 报错,final修饰的对象无法修改
}
}
抽象类
1.什么是抽象类
1.什么是抽象类:具有共同特征的类之间有共同特征,将这些具有共同特征的类再进一步抽象就成了抽象类,而类本身是不存在的,所以不能创建对象,抽象类和抽象类还可以进一步抽象
2.抽象类属于什么类型:引用数据类型
2.抽象类的定义
这里我们引入一个新的关键组abstract
3.抽象类怎么定义 语法:
[修饰符列表] abstract class 类名{
类体;
}
3.抽象方法
抽象类无法new对象,所以抽象类是用来继承的,而其中的抽象方法就代表了子类的共同特性,供子类实现。
抽象方法的格式:
抽象类关联到一个概念:抽象方法,抽象方法表示没有实现的方法
特点一:没有方法体,以分号结尾
特点二:修饰符里有abstract关键字
例如public abstract void withDraw();等等
栗子
public class 抽象类 {
public static void main (String[] args) {
//new Account();//Account是抽象的,无法实例化
//a的类型是animal,animal是抽象的无法实例化,但是可以实例一个继承他的子类对象
animal a = new Brid();//面向抽象编程,这里是向上转型
a.move();
//编译的时候是animal的move方法
//运行的时候是Brid的move
}
}
abstract class Account{
public Account(String s) {
}
//当定义了一个有参的构造方法后,无参的构造方法系统不再提供,若还想调用无参的构造方法,需要手动定义
public Account() {
}
}
//子类继承抽象类
abstract class CreditAccount extends Account{
//回忆之前的内容,当一个构造方法的第一行没有this()和super()时,会默认有一个super();去调父类的无参构造方法,若父类没有,会报错
public CreditAccount() {
super();
}
}
abstract class animal{
public abstract void move();
}
class Brid extends animal{
//重写抽象方法
public void move(){
System.out.println("鸟儿在飞翔");
}
}
输出结果:
鸟儿在飞翔
接口
1.什么是接口
接口也是一种引用数据类型,编译之后也是一个class文件,接口是完全抽象的,接口是半抽象的,在java语言中,类只支持单继承,接口也同样支持继承,且一个类可以继承多个接口,解决了类只能单继承的问题,接口同抽象类,不能new接口对象,但是可以new一个实现类的对象。
2.如何定义一个接口?
[修饰符列表] interface 接口名{}
注意,接口中只有两种属性:常量和抽象方法
常量:static final 修饰的变量
3.类实现接口
对于继承接口的类,我们称之为这个类实现了接口,关键字implement
栗子有点长(⊙o⊙)
public class text {
public static void main(String[] args) {
//访问接口中的常量
System.out.println(MyMath.PI2);
//MyMath.PI = 1111; 接口中的常量不能修改
//能使用多态吗?可以,和之前多态的语法一样,编译运行时的对象不同
//不能new接口对象,但是可以new实现类对象
MyMath mm = new Abc();
//面向接口编程
System.out.println(mm.sum(1,2));
System.out.println(mm.sum2(1,2));
A a = new D();
B b = new D();
a.m1();
//虽然new了一个D的对象,但是编译器只知道a是A类型的对象,这是典型的多态,即运行和编译存在差别!
//a.m2();A中没有m2方法,报错
b.m2();
//向下转型
B b2 = (B)a;
b2.m2();
//经过测试,接口和接口之间在强转的时候,没有继承关系也可以强转,只是运行时可能会出现classCastExpection错误,建议使用instanceof运算符
M m = new E();
//K k = (K)m;
fly f = new cat();
f.flyable();//肥猫起飞
}
}
//定义接口
interface A{
public void m1();
}
interface B{
public void m2();
}
interface C extends A,B{
public void m3();
}
interface MyMath{
//常量:static final 修饰的变量
public static final double PI=3.1415926;//常量
double PI2 = 3.1415926;//常量的public static final可以省略
public abstract int sum(int a,int b);
//可以去掉public abstract
int sum2(int a,int b);
}
//编写一个非抽象的类,需要重写接口中的抽象方法
class Abc implements MyMath{
//实现接口中的方法
//public不能省略,丢失会导致访问权限更低
public int sum2(int a, int b) {
return a-b;
}
public int sum(int a, int b) {
return 0;
}
}
//一个类可以实现多个接口,并且一定要对抽象方法进行重写
class D implements A,B{
public void m1() {
System.out.println("aaa");
}
public void m2() {
System.out.println("bbb");
}
public void m3(){
System.out.println("ccc");
}
}
interface K{
}
interface M{
}
class E implements M{
}
class animal{}
interface fly{
public void flyable();
}
//继承在前,实现在后
class cat extends animal implements fly{
public void flyable(){
System.out.println("肥猫起飞");
}
}