一.抽象类
1.概述
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
抽象类不能直接new对象了
如:
public abatract void eat();父类知道所有子类都有吃饭的功能,但不给出具体实现
2.抽象类的特点
抽象类特点
a:抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();
b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
用于子类访问父类数据时的初始化
d:抽象类不能直接实例化那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
e:抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法
案例:
package org.westos.demo;
public class MyTest {
public static void main(String[] args) {
/* 抽象类特点
a:抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();
b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
c:抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
用于子类访问父类数据时的初始化
d:抽象类不能直接实例化那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
e:抽象类的子类
要么是抽象类
要么重写抽象类中的所有抽象方法*/
//抽象类的实例化
Animal animal=new Dog();
}
}
abstract class Animal{
String name;
int age;
public abstract void eat();
public abstract void sleep();
}
class Dog extends Animal{
//抽象类的子类重写抽象类中的所有抽象方法
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void sleep() {
System.out.println("狗晚上睡觉");
}
}
//抽象类的子类是抽象类
abstract class Cat extends Animal{
}
//抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
//class Cat{
//报错,有抽象方法的一定是抽象类
//abstract void catchMouse();
//
// }
/*//不报错,证明抽象类不一定有抽象方法
abstract class Cat{
public void study(){
System.out.println("Cat的非抽象方法");
}
}*/
/*abstract class aa{
//抽象类中可以有构造方法,作用是用于子类访问父类数据时的初始化
public aa() {
}
}
class MyTest2 {
public static void main(String[] args) {
//报错,抽象类不能实例化
aa a = new aa();
}
}*/
3.抽象类的成员特点
1.抽象方法强制子类进行重写,非抽象方法可以重写,可以不重写
2.成员变量:既可以是变量,也可以是常量。
构造方法:有。用于子类访问父类数据的初始化。
成员方法:既可以是抽象的,也可以是非抽象的
3. 抽象方法 强制要求子类做的事情。
非抽象方法 子类继承的事情,提高代码复用性。
案例:
package org.westos.demo2;
public abstract class Animal {
//抽象类中的成员变量:既可以是变量,也可以是常量。
String name="李四";
static int age=18;
//抽象类中有构造方法,用于子类访问父类数据的初始化。
public Animal() {
}
//抽象方法强制子类进行重写
public abstract void sleep();
//非抽象方法可重写可不重写
public void eat(){
}
}
class Dog extends Animal{
public Dog() {
}
@Override
public void sleep() {
}
}
4.抽象类的面试题
1. 一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
答案: 可以 . 不能创建对象.
可以啊,这个不是说抽象类必须有抽象方法,这样做唯一的意义就是该类只能作为父类来被继承,而不能实例化对象,意思是该类依然为抽象类,但抽象类不能直接new对象.
2. abstract不能和哪些关键字共存
private 冲突。矛盾。abstract 强制子类重写。但是private 是私用的,子类都不能继承何谈重写
final 冲突,矛盾,final修饰的方法,子类不能重写 但是abstract 强制子类重写
static 没有意义。static 方法不参与重写 但是abstract 强制子类重写
案例:
abstract class Animal{
abstract void eat();
abstract void sleep();
// private 冲突。矛盾。abstract 强制子类重写。但是private 是私用的,子类都不能继承何谈重写
//private abstract void playGame();
//final 冲突,矛盾,final修饰的方法,子类不能重写 但是abstract 强制子类重写
//final abstract void playGame();
// static 没有意义。static 方法不参与重写 但是abstract 强制子类重写
// static abstract void aa();
public void show(){
System.out.println("表演");
}
}
class Cat extends Animal{
@Override
void sleep() {
System.out.println("猫白天睡觉");
}
@Override
void eat() {
System.out.println("猫吃鱼");
}
}
二.接口
1.概述
为了体现事物功能的扩展性,Java中提供了接口来定义额外功能,并不给出具体实现
2.特点
a:接口用关键字interface表示 格式: interface 接口名 {}
b:类实现接口用implements表示 格式: class 类名 implements 接口名 {}
c:接口不能直接实例化
那么,接口如何实例化呢?
按照多态的方式来实例化。
d:接口的子类
a:可以是抽象类。但是意义不大。
b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
案例:
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
//为了体现事物功能的扩展性
A a=new B();
a.a();//B重写了A的a方法
a.b();//B重写了A的b方法
A a1=new D();
a1.a();//重写a方法
a1.b();//重写b方法
((D) a1).haha();//重写哈哈方法
}
}
interface A{
//接口前的方法默认为public abstract,可以省略但是有
public abstract void a();
public abstract void b();
}
//接口的子类可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
class B implements A{
@Override
public void a() {
System.out.println("B重写了A的a方法");
}
@Override
public void b() {
System.out.println("B重写了A的b方法");
}
}
//接口的子类可以是抽象类。但是意义不大
abstract class C extends B{
public abstract void haha();
}
class D extends C implements A{
@Override
public void a() {
System.out.println("重写a方法");
}
@Override
public void b() {
System.out.println("重写b方法");
}
@Override
public void haha() {
System.out.println("重写哈哈方法");
}
}
class E extends B implements A{
}
3.接口中的成员特点
1.接口中只能定义常量不能定义变量 并且还是公共的静态常量 因为存在默认修饰符 public static final,不写归不写,但是存在
2.接口中没有构造方法
3.接口中的全部是抽象方法,没有非抽象方法 方法前面有默认修饰符 public abstract,不写归不写,但是存在
案例:
interface Interface{
//int num;//报错,成员变量前面存在默认修饰符public static final,不能定义变量
int num=10;
//接口中没有构造方法
/*public Interface(){
}*/
public abstract void show();
//接口中没有非抽象方法.方法前面有默认修饰符public abstract
// void show2(){}
}
4.类与类,类与接口,接口与接口之间的关系
:类与类,类与接口,接口与接口的关系
a:类与类:
extends 继承关系,并且是单继承,支持多层继承。
b:类与接口:
implements实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。
c:接口与接口:
继承关系,可以单继承,也可以多继承。
接口跟接口直接是继承关系。并且可以多继承。一个接口可以继承多个接口。
案例:
public class MyTest {
public static void main(String[] args) {
//类跟类之间的关系:extends 继承关系,并且是单继承,支持多层继承。
//类跟接口的关系:implements 实现关系,并且可以多实现。一个类可以实现多个接口。
//一个类在继承一个父类的同时还可以去实现多个接口
//接口跟接口直接是继承关系。并且可以多继承。一个接口可以继承多个接口。
}
}
interface Interface{
}
interface Interface2 extends Interface{
}
interface Interface3 extends Interface,Interface2{
}
class Sun extends Zi implements Interface2,Interface,Interface3{
}
class ZuFu{
}
class Fu extends ZuFu{
}
class Zi extends ZuFu{
}
5.抽象类跟接口的区别
1.成员区别:
1)抽象类中可以定义常量,也可以定义变量;
接口中只能定义常量,因为成员变量前有一个默认修饰符public static final
2)抽象类中的方法可以是抽象方法,也可以是非抽象方法
接口中的方法只能是抽象方法,方法前有一个默认修饰符public abstract
3)抽象类中有构造方法
接口中没有构造方法这一说,因为只有类才会有构造方法的概念
2.关系区别
类与类 继承,单继承
类与接口 实现,单实现,多实现
接口与接口 继承,单继承,多继承
3.设计理念区别
抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
注意事项:
JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用
JDK1.8之后,也可以在接口中定义静态方法
这个default修饰的方法 ,可以给给出方法体,对方法功能具体实现。
JDK1.9 接口中可以定义私有方法与私有静态方法
案例:
package org.westos.demo4;
public class MyTest {
public static void main(String[] args) {
A a=new A();
a.show3();//重写show3
a.show4();//重写show4
a.show6();//重写show6
}
}
abstract class MyDemo{
public MyDemo() {
}
int num;
public static int num2=10000;
public void show(){
}
public abstract void show2();
}
interface Interface{
int a=999;
void show3();
// JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用
// JDK1.8之后,也可以在接口中定义静态方法
public default void show6(){
System.out.println("JDK1.8之后在接口中提供了用default修饰的方法");
}
public static void show7(){
System.out.println(" JDK1.8之后,也可以在接口中定义静态方法");
}
public abstract void show4();
/* public void show5(){
}*/
// int b;
}
class A implements Interface{
@Override
public void show3() {
System.out.println("重写show3");
}
@Override
public void show6() {
System.out.println("重写show6");
}
@Override
public void show4() {
System.out.println("重写show4");
}
}
6.猫的案例
public class Animal {
/* 动物类:姓名,年龄,吃饭,睡觉。
动物培训接口:跳高
猫继承动物类
狗继承动物类
部分猫继承猫类并实现跳高接口
部分狗继承狗类并实现跳高接口
通过抽象类测试基本功能。
通过接口测试扩展功能。
只测试猫,狗的测试留给学生自己练习*/
String name;
int age;
public void eat(){
System.out.println("吃法");
}
public void sleep(){
System.out.println("睡觉");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃饭");
}
@Override
public void sleep() {
System.out.println("猫睡觉");
}
}
public class JiaFeiMao extends Cat implements Jump {
@Override
public void eat() {
System.out.println("加菲猫爱吃千层饼");
}
@Override
public void sleep() {
System.out.println("加菲猫喜欢白天睡大觉");
}
@Override
public void jumpWater() {
System.out.println("加菲猫学会类跳水");
}
}
public class KattyMao extends Cat {
@Override
public void eat() {
System.out.println("katty猫不喜欢吃");
}
@Override
public void sleep() {
System.out.println("katty猫不喜欢睡");
}
public void show(){
System.out.println("katty猫喜欢展示自己的才艺");
}
}
public interface Jump {
void jumpWater();
}
public class MyTest {
public static void main(String[] args) {
Animal animal1 = new Animal();
animal1.eat();//吃法
animal1.sleep();//睡觉
System.out.println(animal1.age);//0
System.out.println(animal1.name);//null
System.out.println("=======================");
Animal an2 = new Cat();
an2.name = "李四猫";
an2.age = 18;
System.out.println(an2.age);//18
System.out.println(an2.name);//李四猫
an2.sleep();//猫睡觉
an2.eat();//猫吃饭
System.out.println("============================");
Cat cat = new JiaFeiMao();
cat.name = "加菲猫";
cat.age = 77;
System.out.println(cat.age);//77
System.out.println(cat.name);//加菲猫
cat.sleep();//加菲猫喜欢白天睡大觉
cat.eat();//加菲猫爱吃千层饼
//向下转型
JiaFeiMao j1 = (JiaFeiMao) cat;
j1.jumpWater();//加菲猫学会类跳水
System.out.println("=======================");
KattyMao k1 = new KattyMao();
//多态
Cat c = k1;
c.name="katty猫";
c.age=111;
System.out.println(c.name);//katty猫
System.out.println(c.age);//111
c.eat();//katty猫不喜欢吃
c.sleep();//katty猫不喜欢睡
((KattyMao) c).show();//katty猫喜欢展示自己的才艺
}
}