标签:obj 相关 值类型 方式 运行 小结 动作 ext except
接口是多个类的公共规范,是一种引用数据类型,最重要的内容是其中的抽象方法。接口是Java语言中一种引用类型,是方法的集合 ,内部主要封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)
一个类通过继承接口的方式,从而来继承接口的抽象方法。接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
接口的定义,与定义类方式相似,不同的是使用interface
关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。基本格式如下
public interface 接口名称 {
// 抽象方法(任何版本都能定义)
// 默认方法
// 静态方法
// 私有方法
}
回顾抽象方法:使用 abstract 关键字修饰,可以省略,没有方法体。该方法供子类实现使用。格式如下:
public interface InterFaceName {
public abstract void methodAbs1();
public void methodAbs2();
abstract void methodAbs3();
void methodAbs4();
}
public abstract
,也可以省略,但不能是别的关键字默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写
静态方法:使用 static 修饰,供接口直接调用
代码如下:
public interface InterFaceName {
public default void method() {
// 执行语句
}
public static void method2() {
// 执行语句
}
}
私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用。
代码如下:
public interface InterFaceName {
private void method() {
// 执行语句
}
}
格式:
public class 实现类名称 implement 接口名称{
//...
}
注意:实现类必须覆盖重写接口中所有的抽象方法,除非实现类是抽象类
可以继承,可以重写,二选一,但是只能通过实现类的对象来调用
格式:
public default 返回值类型 方法名称(参数列表){
方法体
}
注:接口中的默认方法,可以解决接口升级问题
定义接口:
public interface Liveable{
public default void fly(){
System.out.println("天上飞");
}
}
定义实现类:
public class Animal implement Liveable{
//什么都不用写,直接调用
}
定义测试类:
public class InterfaceDemo{
public static void main(String[] args){
//创建子类对象
Animal a = new Animal();
//调用默认方法
a.fly();
}
//结果:天上飞
}
定义接口
public interface LiveAble {
public default void fly(){
System.out.println("天上飞");
}
}
定义实现类
public class Animal implements LiveAble {
@Override
public void fly() {
System.out.println("自由自在的飞");
}
}
定义测试类
public class InterfaceDemo {
public static void main(String[] args) {
// 创建子类对象
Animal a = new Animal();
// 调用重写方法
a.fly();
}
}
输出结果:
自由自在的飞
静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
注意:不能通过接口实现类的对象来调用接口当中的静态方法。应这样用接口名称.静态方法名(参数)
定义接口:
public interface Liveable{
public sataic void run(){
systenm.out.println("这是接口静态方法");
}
}
定义实现类
public class Animal implements LiveAble {
// 无法重写静态方法
}
定义测试类
public class InterfaceDemo {
public static void main(String[] args) {
// Animal.run(); // 【错误】无法继承方法,也无法调用
LiveAble.run(); //
}
}
输出结果:
跑起来~~~
如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助。
解决多个默认方法之间代码重复问题。格式:
private 返回值类型 方法名称(参数列表){
方法体
}
解决多个静态方法之间代码重复问题。格式:
private taatic 返回值类型 方法名称(参数列表){
方法体
}
接口中也可以定义“成员变量”,但必须使用public static final 三个关键字进行修饰。从效果上看就是接口的常量
格式:
public static final 数据类型 常量名称 = 数据值
如:public static final num = 10;//这是一个常量。一旦赋值不可修改
注意:
? ① 接口当中的常量,可以省略public static final ,不写也是这样。初学不省略。
? ② 接口当中的常量,必须进行赋值。因为有final关键字存在
? ③ 接口中常量名称,使用完全大写的字母,用下划线进行分隔。如NUM_OF_CLASS
成员变量其实是常量,格式:
[public] [static] [final] 数据类型 常量名称 = 数据中
接口中最重要的就是抽象方法,格式:
[public] [abstruct] 返回值类型 方法名称(参数列表)
从Java 8开始,接口里允许定义默认方法,格式:
public default 返回值类型 方法名称(参数列表){方法体}
从Java 8开始,接口里允许定义静态方法,格式:
[public] static 返回值类型 方法名称(参数列表){方法体}
从Java 9开始,接口里允许定义私有方法,格式:
private 返回值类型 方法名称(参数列表){方法体}
private static 返回值类型 方法名称(参数列表){方法体}
接口没有静态代码块和构造方法
一个类的直接父类是唯一的,但一个类可以同时实现多个接口
格式:
public class MyInterface implements InterfaceA,InterfaceB{
//覆盖重写所有抽象方法
}
如果实现类所实现的多个接口中,存在重复的抽象方法,那么只需覆盖重写一次即可
如果实现类所实现的多个接口中,存在充分的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写
如果实现类没有覆盖重写所有接口当中的抽象方法,那么实现类就必须是一个抽象类
一个类如果其直接父类当中的方法和接口当中的默认方法产生了冲突,那么优先使用父类中的方法
一个接口能继承另一个或者多个接口,这和类之间的继承比较相似。接口的继承使用 extends 关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。
注意:
多态是继封装、继承之后,面向对象的第三大特性 。多态是同一个行为具有多个不同表现形式。多态性是对象多种表现形式的体现。
如学生A是一名学生,同时也是一个人。学生A这个对象既有学生形态,也有人类形态。一个对象拥有多个形态这就是对象的多态性
前提
代码中体现多态性,就是一句话:父类引用指向子类对象
父类名称 对象名 = new 子类名称();
Fu obj = new Zi();
//或者
接口名称 对象名 = new 实现类名称();
在多态的代码中,成员方法的访问规则是:
实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利 ,多态的好处体现在可以使程序编写的更简单,并有良好的扩展
多态的转型分为向上转型与向下转型两种
父类名称 对象名 = new 子类名称();
Animal animal = new Cat();//创建一只猫,当作动物看待
子类类型 变量名 = (子类类型) 父类变量名;
定义类
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void catchMouse() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void watchHouse() {
System.out.println("看家");
}
}
定义测试类
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
Cat c = (Cat)a;
c.catchMouse(); // 调用的是 Cat 的catchMouse
}
}
必须保证对象原本创建的时候,就是猫,后面才能向下转型为猫
如果对象原本创建的时候不是猫,若非要向下转型为猫就会报错。这段代码可以通过编译,但是运行时,却报出了 ClassCastException
类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。
int num = (int)10.0; //可以
,int unm = (int)10.8;
不行,会损失精度为了避免上面这种情况的发生,Java提供了 instanceof
关键字,给引用变量做类型的校验,格式如下
变量名 instanceof 数据类型
,如果变量属于该数据类型,返回true,否则返回false ```
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 调用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 调用的是 Dog 的 watchHouse
}
}
}
标签:obj 相关 值类型 方式 运行 小结 动作 ext except
原文地址:https://www.cnblogs.com/lf-637/p/12986536.html