——我是LGM_Hakka,请多多指教。
抽象类、接口、包
抽象类
1、抽象类概述
使用abstract关键字修饰的类。
- 如果多个类中存在相同的方法声明,而方法体不一样,我们就可以只提取方法声明。
- 如果一个方法只有方法声明,没有方法体,那么这个方法必须用抽象修饰。
- 而一个类中如果有抽象方法,这个类必须定义为抽象类。
2、抽象方法
一个没有方法体的方法,并且使用abstract关键字修饰。
3、抽象类的特点
- 抽象类与抽象方法都被abstract关键字修饰
- 有抽象方法的是抽象类或接口。抽象类中不一定有抽象方法,但是接口中的方法全是抽象的。
- 抽象类本身是不能够被实例化的,但是可以通过继承它的子类对象,进行实例化
- 如果一个类继承了一个抽象类,那么这个类要么也是抽象类,要么就需要重写父类抽象类中的所有抽象方法。否则会报错。
4、抽象类中的成员特点
- 抽象类中的成员变量:即可以有常量,也可以有变量
- 抽象类中的成员方法:可以有抽象方法,也可以有非抽象方法。
- 抽象方法它是强制要求子类做某些事的。
- 非抽象方法是为了提高代码的复用性。
- 抽象类中是有构造方法的。
- 抽象类中的构造方法的作用:在子类访问父类数据前对父类数据进行初始化的。
5、抽象类的好处
- 抽象类可以强制子类做某些功能
6、abstract不能和哪些关键字共存
- final --- 被final修饰的方法不能被重写,而抽象方法最终都是要被重写.
- static --- 如果一个方法被static 修饰那么这个方法就可以直接用类名.调用(这个方法是没有方法体的这样做没有意义)
- private --- 被 private 修饰的方法在子类中是看不见的,所以这个抽象方法也是不能被重写的.
7、实例
//定义一个抽象类
abstract class A {
// 姓名
private String name;
// 年龄
private int age;
// 带参构造
public A(String name, int age) {
this.name = name;
this.age = age;
}
// 获取姓名
public String getName() {
return name;
}
// 获取年龄
public int getAge() {
return age;
}
// 抽象方法
abstract void show();
// 非抽象方法
void info() {
System.out.println(getName());
}
}
// 定义一个非抽象类,继承抽象类A
class B extends A {
// 带参构造
public B(String name, int age) {
super(name, age);
}
// 重写父类中抽象方法
void show() {
System.out.println(getAge());
}
}
// 测试类
public class Test {
public static void main(String[] args) {
// 创建一个B对象,并调用其方法
B b = new B("张三", 22);
b.info();
b.show();
}
}
接口
1、接口的定义
interface 接口名;
interface A {}
2、类与接口之间的关系
类实现接口,用关键字implements连接
例如: class 类名 implements 接口名(若实现有多个接口,接口与接口之间用,分开)
interface A {}
interface B {}
interface C {}
class D implements A,B,C {}
3、接口的特点
- 接口是不能被实例化的
- 接口中的方法都是抽象的
- 实现接口的类,要么是抽象类,要么重写接口中所有的方法
4、接口中的成员变量、成员方法及构造方法
- 成员变量
- 接口中的成员变量都是常量
- 因为接口的成员变量的默认修饰符是:public static final。建议自己以手动添加
- 接口中的成员变量都是常量
在Java接口中定义常量,下面语法正确的是(ABC)。
A. static final int MALE = 1;
B. final int MALE = 1;
C. int MALE = 1;
D. private int MALE = 1;
- 成员方法
- 接口中成员方法都是抽象方法。所以实现接口的类要么是抽象类,要么重写接口中所有的方法
- 因为接口的方法的默认修饰符是:public abstract...
- 接口中成员方法都是抽象方法。所以实现接口的类要么是抽象类,要么重写接口中所有的方法
- 构造方法
- 接口没有构造方法。
- 如果一个类没有继承父类,那么这个类就会默认继承Object类
- 接口没有构造方法。
5、接口的思想特点
A:接口是对外暴漏的原则。
B:接口是程序对外的功能扩展。
C:接口的出现降低耦合性。
D:接口可以用来多实现。
6、实例
//定义一个接口A
interface A {
public static final int i = 10;
public abstract void show();
}
class B implements A{
//重写接口中的show方法
public void show() {
System.out.println("重写接口中的show方法");
//调用接口A中的i常量
System.out.println(i);
}
}
//测试类
class Test {
public static void main(String[] args) {
//创建B的对象,并调用B中的重写show的方法
B b = new B();
b.show();
}
}
接口与抽象类的区别
抽象类:
- 成员变量:可以是变量,也可以是常量。
- 构造方法:有构造方法。
- 成员方法:可以是抽象方法,也可以是非抽象方法。
接口:
- 成员变量:只能是常量。 默认修饰符 public static final
- 构造方法:无构造方法
- 成员方法:只能是抽象方法。 默认修饰符 public abstract
接口、类的关系
类与类关系
继承关系。而且只能单继承,但是可以多层继承。
类与接口的关系
实现关系。可以单实现,也可以多实现。
并且还可以在继承一个类的同时,实现多个接口。
接口与接口的关系
继承关系。可以单继承,也可以多继承。
因为接口不会出现方法调用不明确的情况
类与抽象类的关系
继承关系
包
带包的定义
o 格式:package 包名(可以是单级包,也可以是多级包)
o 带包的编译顺序:
package包名 >> import 导包 >> 定义类 class
o 不同包下类之间的访问和导包的常见问题
§ 提示:找不到Demo类
解决方案:使用全路径名
§ 提示:某类无法访问
解决方案:对类使用public修饰
抽象类与接口的实例
/*
乒乓球运动员和教练
篮球运动员和教练
为了出国交流,乒乓球运动员和教练需要说英语。
请你用所学知识,分析这里应该有哪些类,抽象类,接口。
*/
/*
思路:
1、将兵乓球运动员、篮球运动员、兵乓球教练及篮球教练各定义一个实例类
2、将兵乓球运动员、篮球运动员抽象成一个抽象类【运动员】
3、将兵乓球教练、篮球教练抽象成一个抽象类【教练类】
4、因为不管是运动员还是教练都是人,所以再将运动员和教练抽象成一个抽象类【人】
5、应为只有兵乓球运动员和兵乓球教练才要除过交流,所以,不能将说英语定义在【人那个抽象类中,
将于接口的形式来定义。
*/
//定义【说英语】接口
interface English {
// 定义说【speak】抽象方法
public abstract void speak();
}
// 定义【Person】抽象类
abstract class Person {
// 封装姓名
private String name;
// 封装年龄
private int age;
// 定义Person类的空参数构造函数
public Person() {
}
// 定义Person类的带参数构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 设置姓名
public void setName(String name) {
this.name = name;
}
// 获取姓名
public String getName() {
return name;
}
// 设置年龄
public void setAge(int age) {
this.age = age;
}
// 获取年龄
public int getAge() {
return age;
}
// 打印姓名
public void show() {
System.out.println("姓名:" + name + "\t年龄:" + age);
}
// 定义睡觉[sleep]的方法
public void sleep() {
System.out.println("睡觉啦....");
}
// 定义吃饭[eat]的抽象方法
public abstract void eat();
}
// 定义运动员[Sportman]抽象类
abstract class Sportsman extends Person {
// 定义Sportsman类的空参数构造函数
public Sportsman() {
super();
}
// 定义Sportsman类的带参数构造函数
public Sportsman(String name, int age) {
super(name, age);
}
// 定义运动员的练习抽象方法
public abstract void practice();
}
// 定义教练[coach]抽象类
abstract class Coach extends Person {
// 定义Coach类的空参数构造函数
public Coach() {
super();
}
// 定义Sportsman类的带参数构造函数
public Coach(String name, int age) {
super(name, age);
}
// 定义教练的教抽象方法
public abstract void teach();
}
// 定义乒乓球运动员类[PingPongPlayer],因为要用英语交流,所以,实现接口[English]
class PingPongPlayer extends Sportsman implements English {
// 定义PingPongPlayer类的空参数构造函数
public PingPongPlayer() {
super();
}
// 定义PingPongPlayer类的带参数构造函数
public PingPongPlayer(String name, int age) {
super(name, age);
}
// 重写[English]接口的[spreak]方法
public void speak() {
System.out.println("乒乓球运动员用英语交流...");
}
// 重写父类[Sportsman]中的[practice]方法
public void practice() {
System.out.println("乒乓球运动员练习打乒乓球....");
}
// 重写[Person]类中的[eat]方法
public void eat() {
System.out.println("乒乓球运动员吃粤菜");
}
}
// 定义篮球运动员类[BasketballPlayer],因为不用英语交流,所以,不需要实现接口[English]
class BasketballPlayer extends Sportsman {
// 定义BasketballPlayer类的空参数构造函数
public BasketballPlayer() {
super();
}
// 定义BasketballPlayer类的带参数构造函数
public BasketballPlayer(String name, int age) {
super(name, age);
}
// 重写父类[Sportsman]中的[practice]方法
public void practice() {
System.out.println("篮球运动员练习打篮球....");
}
// 重写[Person]类中的[eat]方法
public void eat() {
System.out.println("篮球运动员吃川菜");
}
}
// 定义乒乓球教练类[PingPongCoach],因为要用英语交流,所以,实现接口[English]
class PingPongCoach extends Coach implements English {
// 定义PingPongCoach类的空参数构造函数
public PingPongCoach() {
super();
}
// 定义PingPongCoach类的带参数构造函数
public PingPongCoach(String name, int age) {
super(name, age);
}
// 重写[English]接口的[spreak]方法
public void speak() {
System.out.println("乒乓球教练用英语交流...");
}
// 重写父类[Coach]中的[teach]方法
public void teach() {
System.out.println("乒乓球教练教怎么打乒乓球....");
}
// 重写[Person]类中的[eat]方法
public void eat() {
System.out.println("乒乓球教练吃湘菜");
}
}
// 定义篮球教练类[BasketballCoach],因为要用英语交流,所以,实现接口[English]
class BasketballCoach extends Coach {
// 定义BasketballCoach类的空参数构造函数
public BasketballCoach() {
super();
}
// 定义BasketballCoach类的带参数构造函数
public BasketballCoach(String name, int age) {
super(name, age);
}
// 重写父类[Coach]中的[teach]方法
public void teach() {
System.out.println("篮球教练教怎么打乒乓球....");
}
// 重写[Person]类中的[eat]方法
public void eat() {
System.out.println("篮球教练吃东北菜");
}
}
class SportDemo {
public static void main(String[] args) {
// 创建乒乓球运动员对象
PingPongPlayer ppp = new PingPongPlayer("张继科", 27);
ppp.show();
ppp.speak();
ppp.practice();
ppp.eat();
System.out.println("-----------------------------");
// 创建乒乓球教练对象
PingPongCoach ppc = new PingPongCoach("刘国梁", 56);
ppc.show();
ppc.speak();
ppc.teach();
ppc.eat();
System.out.println("-----------------------------");
// 创建篮球运动员对象
BasketballPlayer bp = new BasketballPlayer("姚明", 40);
bp.show();
bp.practice();
bp.eat();
System.out.println("-----------------------------");
// 创建篮球教练对象
BasketballCoach bc = new BasketballCoach("李四", 57);
bc.show();
bc.teach();
bc.eat();
System.out.println("-----------------------------");
}
}