1. final 关键字
final:最终的
1.final可以用来修饰的结构:类,方法,变量
2.final用来修饰一个类:此类不能被其它类继承;
如 String类,System类,StringBuffer类
3.final用来修饰方法:该方法不能被重写 * 如 Object 类中的 getClass()
4.final用来修饰变量,此时的变量称为常量。
final修饰属性,可以赋值的位置:显式初始化,代码块中初始化,构造器中初始化
final修饰局部变量:
5.static final 可以修饰:属性(全局常量,接口中常用),方法
static 修饰:属性,方法,代码块,内部类
final 修饰:属性,方法
public class FianlTest {
public static void main(String[] args) {
Te03 t = new Te03();
t.Show(10);
}
}
class Te03{
public void Show( final int a){//形参是一个常量
System.out.println(a);
// a = 20;不能再赋值
// 局部变量
final int age = 100;
// age += 10;报错
}
}
2. 抽象类与抽象方法
abstract 修饰类:抽象类
1.此类不能实例化
2.抽象类一定有构造器,虽不能实例化,但便于子类实例化时调用
3.开发中,都会提供抽象类的子类,让子类对象实例化
abstract 修饰方法:抽象方法
1.只有方法的声明,没有方法体;
2.包含抽象方法的类,一定是抽象类;反之,抽象类中不一定含有抽象方法
3.子类重写了父类所有的抽象方法后,此子类方可实例化,
若没有重写所有抽象方法,此子类也必须是一个抽象类
public class AbstractClass {
public static void main(String[] args) {
// AbstractTest a = new AbstractTest();抽象类不能实例化,但是构造器还是必须存在,以便
AbTest a = new AbTest();
}
}
abstract class AbstractTest{//抽象类
String name;
int age;
public AbstractTest(){};
public AbstractTest(String name,int age){
this.name = name;
this.age = age;
}
public abstract void eat();//大括号也算方法体,后面加分号即可
// {
// System.out.println("吃饭饭");
// }
public void sleep(){
System.out.println("睡觉觉");
}
}
class AbTest extends AbstractTest{
String gender;
//子类重写了父类所有的抽象方法后,此子类方可实例化
@Override
public void eat() {
}
}
3. 接口
一方面:C++ 支持多重继承,而 Java 支持单继承,有了接口,可以弥补单继承的缺点;
另一方面:有时必须从几个类中抽取一些共同的行为特征,而它们之间没有继承的关系;
/**
* 接口:一种规范,主要功能是被实现类实现
* 1.接口使用 interface 来定义
* 2.Java中,接口和类是并列的两个结构
* 3.定义接口以及接口的成员
* 3.1 JDK7及以前,只能定义全局常量和抽象方法
* 全局常量:public static final 可以省略
* 抽象方法:public abstract 可以省略
* 3.2 JDK8,除全局常量,抽象方法外,还可以定义静态方法,默认方法;
*
* 4.接口中不能定义构造器,因此接口不可以实例化
*
* 那么如何调用接口中的抽象方法呢,其与类产生关系:
* 5.java中,接口通过类去实现
* 若实现类覆盖了接口中的所有抽象方法,该实现类可以实例化;
* 若没有全部覆盖,该实现类须为抽象类;
* 6.Java 可以实现多个接口,弥补了 Java 单继承的局限性
* 若需要继承,先继承,再实现
* 7.接口与接口是继承关系,且多继承
* 类与类是继承关系:单继承
* 类与接口是实现关系:同时实现多个接口
*
*
* 8.接口的具体使用:体现多态性
* 接口:实际上可以看做一种规范
* 开发中,体会面向接口编程;
*/
public class InterfaceTest {
public static void main(String[] args) {
// 实现类覆盖了接口中的所有抽象方法,该实现类可以实例化;
Test09 T = new Test09();
T.eat();
}
}
//接口1
interface Int{
//全局变量
public static final int age = 19;
String name = "刘备备";
//抽象方法
public abstract void eat();
void sleep();
//接口中不能定义构造器
// public Int(){}
}
interface Int02{
String gender = "man";
void study();
}
abstract class People{
String name;
public void run(){
System.out.println("跑步");
}
public abstract void walk();
}
//类实现接口,要么重写接口中的所有抽象方法,要么将类声明为静态的
class Test09 extends People implements Int,Int02{
// java 可以实现多个接口,弥补了 Java 单继承的局限性
// 若需要继承,先继承,再实现
public void eat(){
System.out.println("还吃");
}
public void sleep(){
System.out.println("睡不着");
}
@Override
public void study() {
}
@Override
public void walk() {
}
}
interface A{
void A01();
}
interface B{
void A02();
}
//接口与接口是继承关系,且多继承
interface C extends A,B{
//不需要重写全部抽象类,因为接口也是抽象的(含有抽象方法)
}
接口的具体使用:体现多态性
接口:实际上可以看做一种规范
开发中,体会面向接口编程;
/**
* 接口的多态性
*/
class UseTest{
public static void main(String[] args) {
Computer com = new Computer();
// 1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();//抽象方法随着类的加载而加载
com.transform(flash);//体现了多态性:Usb是接口,没有构造器,不能实例化。Usb usb = new Flash;
// 2.创建了接口的非匿名实现类的匿名对象
com.transform(new Printer());//new Printer() = new Printer
// 3.创建了接口的匿名实现类的非匿名对象
}
}
class Computer{
public void transform(Usb usb){
usb.start();
System.out.println("具体传输细节!");
usb.stop();
}
}
//接口:一种规范
interface Usb{
void start();
void stop();
}
//实现类:闪存
class Flash implements Usb{
//重写接口的方法
@Override
public void start() {
System.out.println("闪存读取内容");
}
@Override
public void stop() {
System.out.println("闪存读取结束");
}
}
//实现类:打印机
class Printer implements Usb{
//重写接口的方法
@Override
public void start() {
System.out.println("打印机读取内容");
}
@Override
public void stop() {
System.out.println("打印机结束读取内容");
}
}
JDK 8 :除定义全局常量,抽象方法外,
还可以定义静态方法,默认方法
1.接口中定义的静态方法只能接口自己使用,无法继承给子类
2.对象可以调用接口中的静态方法,若默认方法被子类重写,调用的是重写后的
3.类优先原则: * 若子类(实现类)继承的父类/实现的接口中有同名同参的方法
在子类不重写的情况下,默认调用的是父类中同名同参的方法
4.倘若实现类只实现了多个接口,不存在继承,多个接口中有同名同参的默认方法
那么在实现类没有重写此方法的情况下,会报错 * 这就需要在实现类中重写该默认方法
总之,以上是极端情况。接口与父类的方法不要同名同参即可;
/**
* JDK8 :除定义全局常量,抽象方法外,
* 还可以定义静态方法,默认方法
*
* 1.接口中定义的静态方法只能接口自己使用,无法继承给子类
*
* 2.对象可以调用接口中的静态方法,若默认方法被子类重写,调用的是重写后的
*
* 3.类优先原则:
* 若子类(实现类)继承的父类/实现的接口中有同名同参的方法
* 在子类不重写的情况下,默认调用的是父类中同名同参的方法
*
* 4.倘若实现类只实现了多个接口,不存在继承,多个接口中有同名同参的默认方法
* 那么在实现类没有重写此方法的情况下,会报错
* 这就需要在实现类中重写该默认方法
*/
public class NewCharacterInterface {
public static void main(String[] args) {
ShowImple s = new ShowImple();
// 接口中定义的静态方法只能接口自己使用,无法继承给子类
// s.method1();报错
// 对象可以调用接口中的静态方法,若默认方法被子类重写,调用的是重写后的
s.method2();//调用的是实现类重写的方法
s.method3();//接口与父类的方法相同,调用父类的方法
}
}
interface Show{
//静态方法
public static void method1(){
System.out.println("这是静态方法");
}
//默认方法
public default void method2(){
System.out.println("这是默认方法");
}
public default void method3(){
System.out.println("这是方法3");
}
}
interface Show2{
public default void method3(){
System.out.println("这是Show2的默认方法method3");
}
}
//实现类
class ShowImple extends Fu implements Show,Show2{
public void method2(){
System.out.println("被重写的方法method2");
}
@Override
public void method3() {
super.method3();//父类中的方法
System.out.println("重写的方法3");//自己重写的方法
Show.super.method3();//接口Show中同名同参的默认方法
Show2.super.method3();//接口Show2中同名同参的默认方法
}
}
class Fu{
public void method3(){
System.out.println("父类的方法");
}
}