java重点——面向对象--抽象类、接口
1、抽象类
1.1、概述
当一个类中,没有足够的信息去描述一件具体的事物(对象)时,那么这个类就要定义成抽象类。
1.2、定义抽象类的语法和特征
使用 abstract 关键字来定义抽象类,语法如下:
访问修饰符 abstract class 类名{
}
抽象类的特点:
●抽象类中可以有构造方法,但是不能创建(new)对象
● 普通类中定义的属性和方法,都可以在抽象类中定义
●抽象类中,可以存在抽象方法
●抽象方法,定义语法:
访问修饰符 abstract 返回值类型 方法名(参数列表);
● 抽象方法没有方法体,只有方法的声明
● 抽象类中的抽象方法,必须由子类来实现;如果子类没有实现,则子类也要定义成 抽象类,由子类的子类来实现,以此类推。
● 抽象类中,可以没有抽象方法,但是如果一个类中有一个方法是抽象的,那么这个 类就一定是抽象类。
package com.bdit;
/*
抽象类
*/
public class Test3 {
public static void main(String[] args) {
ChangShape cs = new ChangShape(10, 20);
cs.area();
cs.zhouChang();
}
}
//定义抽象类
abstract class Shape {
int height;
int width;
public Shape(int height, int width) {
this.height = height;
this.width = width;
}
public void display() {
System.out.println("抽象类中的普通方法");
}
public static void t1() {
System.out.println("抽象类中的静态方法");
}
//面积
public abstract void area();
//周长
public abstract void zhouChang();
}
//子类
class ChangShape extends Shape{
public ChangShape(int h, int w) {
super(h, w);
}
public void area() {
System.out.println("长方形的面积:" + (super.height * super.width));
}
public void zhouChang() {
System.out.println("长方形的周长:" + (super.height + super.width) * 2);
}
}
2、接口
2.1、概述
接口,是 Java 语言中一种引用类型,是方法的集合,也是一种标准。如果说类的内部封装了 成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK7 之前)、默认方法和静态方法(JDK8),私有方法(JDK9)。
【接口,就是用来否则定义公共的方法或者说标准的】
接口的定义,它与定义类方式类似,但是使用 interface 关键字,它也会被编译成 class 文件,但一定要明确它并不是类,而是另外一种引用数据类型。
接口的使用,它不能创建对象,但是可以被实现(implements),类似于被继承。一个实现接 口的类(可以看作是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以 调用方法了,否则它必须是一个抽象类。
接口特点总结:
●接口中不能有构造方法,也不能创建接口的对象
●接口中可以有抽象方法,只有方法的声明,没有方法体
●接口中所有的抽象方法,只能使用 public 来修饰,就算不加访问修饰符,默认也是 public
●接口中定义的变量,都是静态的常量,而且完整的修饰语法:
public static final 数据类型 常量名=常量值;
接口中可以简写,直接写 数据类型 常量名=常量值;
●接口需要由类来实现,而且一个类可以实现多个接口,接口之间用逗号分隔
●接口可以弥补 java 中的单一继承,也就是说接口可以实现多继承
2.2、接口的定义
语法格式:
public interface 接口名称{
//常量
//抽象方法
//默认方法
//静态方法
//私有方法
}
接口命名也是采用大驼峰命名法
含有抽象方法
抽象方法:使用 abstract 关键字修饰,但是也可以省略,没有方法体,该方法供子类来实现。
package com.bdit;
//定义抽象方法的接口
public interface InterfaceDemo1 {
public abstract void method1();
public void method2();
void method3();
}
含有默认方法和静态方法
默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写
静态方法:使用 static 修饰,供接口直接调用
package com.bdit;
//默认方法和静态方法
public interface InterfaceDemo2 {
public default void d1(){
System.out.println("接口中的默认方法");
}
public static void s1(){
System.out.println("接口中的静态方法");
}
}
含有私有方法和私有静态方法
私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用
package com.bdit;
// 私有方法
public interface InterfaceDemo3 {
private void p1() {
System.out.println("接口中的私有方法");
}
private static void p2() {
System.out.println("接口中的私有静态方法");
}
}
2.3、接口的基本实现
实现的概述
类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口 的子类,实现类类似继承,格式类似,只是关键字不同,实现接口使用 implements 关键字。
●判断继承关系是否成立,可以通过 “is-a”的方式
●判断实现类和接口的关系,可以通过“like-a”的方式
●实现接口也是一种特殊的继承关系
非抽象子类实现接口:
●必须重写接口中所有抽象方法
●继承了接口的默认方法,即可以直接调用,也可以重写
实现格式:
访问修饰符 class 类名 implements 接口名{
}
抽象方法的使用
实现类必须全部实现
package com.bdit;
public class Impl01 implements InterfaceDemo1 {
public static void main(String[] args) {
Impl01 impl01 = new Impl01();
impl01.method1();
impl01.method2();
impl01.method3();
}
@Override
public void method1() {
System.out.println("方法 1");
}
@Override
public void method2() {
System.out.println("方法 2");
}
@Override
public void method3() {
System.out.println("方法 3");
}
}
默认方法的使用
可以继承,可以重写,二选一,但是只能通过实现类的对象来调用
1.继承默认方法,代码如下:
package com.bdit;
public class Impl02 implements InterfaceDemo2 {
public static void main(String[] args) {
Impl02 impl02 = new Impl02();
impl02.d1();
InterfaceDemo2.s1();
}
}
2.重写默认方法
package com.bdit;
public class Impl02 implements InterfaceDemo2 {
public static void main(String[] args) {
Impl02 impl02 = new Impl02();
impl02.d1();
InterfaceDemo2.s1();
}
public void d1() {
System.out.println("这是对接口默认方法的重写");
}
}
静态方法的使用
静态与类中静态方法使用一样,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用。
package com.bdit;
public class Impl03 implements InterfaceDemo2{
public static void main(String[] args) {
InterfaceDemo2.s1();
}
}
私有方法的使用
●私有方法:只有默认方法可以调用
●私有静态方法,默认方法和静态方法均可调用
如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私 有方法中,供默认方法调用。从设计的角度讲,私有的方法时对默认方法和静态方法的辅助。
package com.bdit;
// 私有方法
public interface InterfaceDemo3 {
private void p1() {
p2();
System.out.println("接口中的私有方法");
}
private static void p2() {
System.out.println("接口中的私有静态方法");
}
public default void d2() {
p1();
}
}
2.4、接口的多实现
在继承中,一个类只能继承一个父类。对接口而言,一个类可以实现多个接口,这叫接口的 多实现。并且一个类能继承一个父类,还可以同时实现多个接口。
语法格式:
访问修饰符 class 类名 [extends 父类] implements 接口 1,接口 2,接口 3,…{
}
[]:表示可选操作
抽象方法
接口中,有多个抽象方法时,实现类必须重写所有的抽象方法,如果抽象方法有重名,只需要重写一次。
package com.bdit;
public class Impl04 implements InterfaceDemo4, InterfaceDemo5 {
public static void main(String[] args) {
Impl04 impl04 = new Impl04();
impl04.t1();
impl04.t2();
}
@Override
public void t1() {
System.out.println("t1");
}
@Override
public void t2() {
System.out.println("t2");
}
}
默认方法
接口中,有多个默认方法时,实现类都可以继承使用,如果默认方法有重名,必须要重写一次。
package com.bdit;
public interface InterfaceDemo4 {
public void t1();
public void t2();
public default void display() {
System.out.println("demo4 中的默认方法");
}
}
package com.bdit;
public interface InterfaceDemo5 {
public void t1();
public void t2();
public default void display() {
System.out.println("demo5 中的默认方法");
}
}
package com.bdit;
public class Impl04 implements InterfaceDemo4, InterfaceDemo5 {
public static void main(String[] args) {
Impl04 impl04 = new Impl04();
impl04.t1();
impl04.t2();
}
@Override
public void t1() {
System.out.println("t1");
}
@Override
public void t2() {
System.out.println("t2");
}
@Override
public void display() {
System.out.println("实现默认方法");
}
}
静态方法
接口中,存在同名的静态方法并不会冲突,原因是只能通过各自的接口名访问静态方法。
优先级的问题
当一个类,即继承了一个父类,又实现了若干个接口时,父类中的成员方法与接口中的默认 方法重名,子类就近选择执行父类的成员方法。
2.5、接口的多继承
一个接口能继承多个接口,接口的继承也是使用 extends 关键字,而且多个接口之间使用逗 号隔开即可。子接口继承了父接口的方法,如果某个类实现了子接口,就要实现子接口以及 父接口中所有的抽象方法。【如果父接口中的默认方法有重名的,那么子接口需要重写一次】。
package com.bdit;
public class Test1 {
public static void main(String[] args) {
}
}
//接口
interface InterfaceDemo6 {
int NUM = 100;//public static final
public void t1();
public void t2();
public default void d1() {
System.out.println("默认方法 1");
}
}
//接口
interface InterfaceDemo7 {
String name = "张三";
public void t3();
public default void d1() {
System.out.println("默认方法 2");
}
}
//子接口
interface SInterfaceDemo1 extends InterfaceDemo6, InterfaceDemo7 {
@Override
default void d1() {
}
}
class MyImpl01 implements SInterfaceDemo1 {
@Override
public void t1() {
System.out.println(InterfaceDemo7.name);
System.out.println(InterfaceDemo6.NUM);
}
@Override
public void t2() {
}
@Override
public void t3() {
}
}
还没有评论,来说两句吧...