Java面向对象(六):抽象

一、抽象类

为什么会有抽象类呢?
会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。
当定义了抽象方法的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。

abstract 抽象的关键字,用abstract修饰的类称为抽象类

  • 抽象类不能被实例化,原因:调用抽象方法没有意义;
  • abstract 修饰方法,抽象方法,抽象方法没有方法的实现(没有方法体)
  • 一个类中如果定义了抽象方法,此类必须是抽象类
  • 一个类如果定义为抽象类,可以有抽象方法,也可以没有抽象方法
  • 没有抽象方法的抽象类的作用是什么?这个类不能实例化,只能作为父类来使用

当前类继承自抽象类,有两种选择 :

  • 1.实现抽象类中的抽象方法
  • 2.否则自己也会称为抽象类

抽象类特点
1、抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中;
2、抽象类不可以直接创建对象,原因:调用抽象方法没有意义;
3、只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类;
4、之所以继承抽象类,更多的是在思想,是面对共性类型操作会更简单;
5、抽象类当中可以有不是抽象的方法;
6、抽象方法不能定义为private的。

注意:抽象方法不能被声明为static、final、private。
抽象类的注意事项
1、抽象类中可以有构造方法,因为抽象类需要子类继承来使用,创建子类的时候,会调用用父类的构造方法。抽象类中的构造方法是子类调用的,只是抽象类本身不能直接创建实例对象而已。
2、抽象类中可以没有抽象方法。没有抽象方法的抽象类,只是不能直接new对象,它是供子类继承使用的。
3、有了抽象方法的类,必须定义为抽象类。

匿名类的使用

  1. 回顾一下,之前我们学习过匿名对象。对比一下学习。
  2. 匿名类:没有起名字的类,在创建抽象类子类实例的时候,直接实现抽象类中的抽象方法,这个是可以的。

二、接口

概念
1.现实生活中接口的例子很多,例如:USB接口、串口(Com)、鼠标、键盘;
2.接口是一种特殊的抽象类,在其中只能定义常量和方法;

语法
[ public ] [ abstract ] interface interfaceName{
// 常量、方法的定义
}

1.有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
2.接口(interface)是抽象方法和常量值的定义的集合。
3.从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。

接口的特点说明:
• 用 interface 来定义;
• 接口中的所有成员变量都默认是由public static final修饰的;
• 接口中的所有方法都默认是由public abstract修饰的。接口没有构造方法;
• 接口中不能有构造器,所以接口不能实例化;
• 实现接口的类中必须提供接口中所有方法的具体实现内容;
• 多个无关的类可以实现同一个接口;
• 一个类可以实现多个无关的接口;
• 与继承关系类似,接口与实现类之间存在多态性;
• 接口也可以继承另一个接口,使用extends关键字;
• 接口像一个“管理者”,只告诉你做什么,而不管怎么做;
• 接口的实质就是做统一的规则;

接口的定义:通过关键字interface来定义,接口中只有常量和抽象方法(JDK8.0以前)

  • 接口中没有构造器,接口也是不能实例化
  • 接口中定义的变量,其实是常量
    • 真实:public static final int a=100;
  • 接口中的方法都是抽象的,默认都有abstract关键字修饰
    • public abstract void test1();

实现接口
 定义Java类的语法格式:
< modifier> class < name> [extends < superclass>]
[implements < interface> [,< interface>]* ] {
< declarations>*
}
 实现接口的类中必须提供接口中所有方法的具体实现内容,否则该类还是 一个抽象类,不能被实例化;
 多个类可以实现同一个接口;
 一个类可以实现多个接口;
 与继承关系类似,接口与实现类之间存在多态性;(接口的引用可以指向它的实现类)

  • 一个类实现一个接口,通过关键字 implements来实现,
  • 实现接口的类必须实现接口的所有抽象方法,否则就会成为抽象类
  • JAVA中是单继承,一个类只能直接继承一个父类,但是一个类可以实现多个接口:
  • 所以,java中通过接口来实现多重继承
  • 接口不能实例化

 常见面试题:抽象类和接口的区别是什么?

接口的继承
 如果实现接口的类中没有实现接口中的全部方法,必须将此类定义为抽象类。
 接口也可以继承另一个接口,使用extends关键字。

接口面试题
接口面试题:下面代码是否能够正确编译?
在这里插入图片描述
在这里插入图片描述

接口面试题:下面代码是否能够正确编译?
在这里插入图片描述
在这里插入图片描述
JDK8版本中 接口部分新特性
 接口默认方法冲突问题及解决:
冲突的描述:一个类实现两个接口,两个接口中有同名的默认方法,就出现了冲突!
冲突的解决:这个时候就要求实现类必须重写接口中的同名方法。
 演示冲突的出现及解决:
接口A和B都有默认方法method1,Test1类实现这两个接口。
 接口中默认方法调用问题:通过“接口名称.super.默认方法”

三、static关键字

static的使用场合
 放在变量前面
• 称为静态变量,或者类变量;
• 为该类的公共变量;
• 对所有对象来说只有一份;
• 通过类的名字直接调用:Test.name
• 放在方法前面
• 称为静态方法,或者类方法;
• 在调用该方法时,不会将对象的引用传递给它;
– 静态方法不再是真的某个对象的调用,所以static方法不能访问非static成员
– static标记的变量或方法由整个类(所有实例)共享,如访问控制权限允许,可不必创建该类对象而直接用类名加‘.’调用。
 static定义静态常量:public static final double PI = 3.14;

静态代码块(static)
一个类中可以使用不包含在任何方法体中的静态代码块(static block ),当类被载入时,静态代码块被执行,且只被执行一次,静态块经常用来进行类属性的初始化。

代码块(非静态)
一个类中可以使用不包含在任何方法体中的代码块。在创建类的实例前调用。
static使用注意事项
 在静态方法里只能直接调用同类中其它的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前不用创建任何对象。
 静态方法不能以任何方式引用this和super关键字。与上面的道理一样,因为静态方法在使用前不用创建任何实例对象,当静态方法被调用时,this所引用的对象根本就没有产生。
 main() 方法是静态的,因此JVM在执行main方法时不创建main方法所在的类的实例对象,因而在main()方法中,我们不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情况,我们在以后的例子中会多次碰到。
 类属性作为该类各个对象之间共享的变量,在设计类时,分析哪些类属性不因对象的不同而改变,将这些属性设置为类属性(static),相应的方法设置为类方法(static)。如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。
成员变量赋值问题
 成员变量可以通过以下方式赋值

  1. 显示对属性初始化赋值,例如:int a = 100;
  2. 在代码块中为属性赋值,例如:{ a = 200;}
  3. 在构造器中为属性赋值。
  4. 创建实例后,通过“对象.属性名”来赋值。
    那么,这几种方式,执行的先后顺序是怎样的?通过示例说明一下。
    属性赋值顺序为:1—2---3—4

四、内部类

 内部类:定义在类的内部的类,称之为内部类。
 内部类分为:成员内部类、局部内部类。
 成员内部类:
• 定义在类的内部,方法的外部。
• 成员内部类分为:静态成员内部类,非静态成员内部类
• 成员内部类,作为一个类,可以定义属性、方法、构造器;可以使用final、abstract来修饰。
• 成员内部类作为外部类的成员,可以调用外部类的成员;可以被static修饰,也可以通过权限修饰符修饰:private、缺省、protected、public
 局部内部类:
定义在方法、构造器中的内部类,为局部内部类。

局部内部类
局部内部类如果调用所在的方法中定义的局部变量,这个局部变量必须定义为final(JDK1.7及以前);JDK1.8及以后,如果在局部内部类中,没有修改这个局部变量,这个局部变量可以不用final修饰。

结束语

继续学习…

猜你喜欢

转载自blog.csdn.net/zhangzhanbin/article/details/111936618
今日推荐