10面向对象(抽象类接口)
Posted shawnyue-08
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10面向对象(抽象类接口)相关的知识,希望对你有一定的参考价值。
抽象类
复习
package org.westos.demo;
/**
* @author lwj
* @date 2020/4/20 16:46
*/
public class MyDemo {
public static void main(String[] args) {
Panda panda = new Panda();
//抽象类AbstractAnimal初始化
//Panda构造方法执行了
System.out.println(panda.num);
//20
}
}
abstract class AbstractAnimal {
/** 抽象类不能直接实例化,但是抽象类存在构造方法,目的是子类在创建对象时需要初始化父类(抽象类)的数据 */
public AbstractAnimal() {
System.out.println("抽象类AbstractAnimal初始化");
//1
}
public void sleep() {
System.out.println("睡觉");
}
/**
* 抽象方法eat
*/
protected abstract void eat();
}
class Panda extends AbstractAnimal {
{
num = 20;
}
int num;
public Panda() {
System.out.println("Panda构造方法执行了");
//2
}
@Override
protected void eat() {
System.out.println("大熊猫吃竹子");
}
}
class Cat extends AbstractAnimal {
public Cat() {
System.out.println("Cat构造方法执行了");
}
@Override
protected void eat() {
System.out.println("猫咪吃小鱼干");
}
}
抽象类的成员特点
- 成员变量:既可以是变量,也可以是常量
- 构造方法:存在,用于子类创建对象时初始化父类数据
- 成员方法:既可以是抽象的,也可以是非抽象的。
- 抽象方法:强制子类实现抽象方法
- 非抽象方法:子类可以重写父类的方法,也可以不重写父类的方法
package org.westos.demo;
/**
* @author lwj
* @date 2020/4/20 17:14
*/
public class MyDemo2 {
public static void main(String[] args) {
Student student = new Student(2);
System.out.println(student.nation);
//中国
student.show();
//我是父类
//子类重写父类的show()方法
student.abstractMethod();
//我是子类
}
}
abstract class AbstractPerson {
public int id = 1;
/** final类型变量在定义后,1、在定义声明时初始化,2、在构造代码块中初始化,3、在构造方法中初始化 */
public final String nation;
{
nation = "中国";
}
public AbstractPerson(int id) {
this.id = id;
}
/** 抽象方法 */
public abstract void abstractMethod();
public void show() {
System.out.println("我是父类");
}
}
class Student extends AbstractPerson {
/*由于父类的构造方法只有一个有参构造,而子类默认无参构造,调用父类的无参构造失败,所以报错,
解决:子类生成一个有参构造,并且显式调用父类有参构造 */
public Student(int id) {
super(id);
}
@Override
public void abstractMethod() {
System.out.println("我是子类");
}
@Override
public void show() {
super.show();
System.out.println("子类重写父类的show()方法");
}
}
抽象类中的面试题
1、一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
可以,不能创建该类对象。
2、abstract不能和哪些关键字共存?
-
abstract修饰方法,子类必须重写该方法,private修饰方法,子类无法继承,则不能重写,所以冲突;
-
abstract修饰类,代表抽象类,子类继承抽象类,与final(修饰类,所修饰的类不能被继承)冲突;
-
abstract修饰方法,代表抽象类中的抽象方法,子类继承抽象类,必须实现抽象类中的抽象方法,和final(修饰方法,所修饰的方法不能被子类重写)冲突;
-
abstract修饰方法,代表抽象方法,没有方法体,static修饰方法代表静态方法,有方法体,不参与重写,不能共存,无意义。
接口
接口的特点
- 接口使用关键字interface表示,interface 接口名 {}
- 类实现接口使用关键字implements表示,class 类名 implements 接口名 {}
- 接口不能实例化,按照多态的方式实例化
- 接口的子类
- 抽象类,abstract class 类名 implements 接口名 {}
- 具体类,要重写接口中的所有抽象方法,class 类名 implements 接口名 {}
package org.westos.demo2;
/**
* @author lwj
* @date 2020/4/20 17:33
*/
public class MyDemo {
}
interface IExpandMethod {
/**
* 打电话
*/
public abstract void call();
}
abstract class AbstractAnimal implements IExpandMethod {
}
class Animal implements IExpandMethod {
@Override
public void call() {
System.out.println("具体类必须实现接口中所有方法");
}
}
接口的成员特点
- 成员变量:只能是常量,并且是public static的,默认修饰符:public static final
- 构造方法:接口中没有构造方法
- 成员方法:只能是抽象方法,默认修饰符:public abstract
类与类、类与接口、接口与接口的关系
- 类与类:继承关系,只能单继承,可以多层继承;
- 类与接口:实现关系,可以单实现,也可以多实现,多个接口之间用
,
隔开,并且可以在继承一个类的同时实现多个接口; - 接口与接口:继承关系,可以单继承,也可以多继承。
//类与类:extends,单继承
//类与接口:implements,单实现,多实现
public final class Integer extends Number implements Comparable<Integer> {}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable{}
//接口与接口:extends,单继承,多继承
public interface List<E> extends Collection<E> {}
public interface SortedMap<K,V> extends Map<K,V> {}
抽象类与接口的区别
成员区别:
- 抽象类:
- 成员变量:可以变量,可以常量
- 构造方法:存在构造方法
- 成员方法:可以抽象,可以非抽象
- 接口:
- 成员变量:只可以常量
- 构造方法:不存在构造方法
- 成员方法:只可以抽象
关系区别:
- 类与类
- 继承,单继承
- 类与接口
- 实现,单实现,多实现
- 接口与接口
- 继承,单继承,多继承
设计理念的区别:
- 抽象类
- 被继承体现的是"is a"的关系,抽象类中定义的是该继承体类的共性功能
- 接口
- 被实现体现的是"like a"的关系,接口中定义的是该继承体系的扩展功能
注意:JDK 1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用。
package org.westos.demo3;
/**
* @author lwj
* @date 2020/4/20 20:09
*/
public interface IExpandMethod {
int NUMBER = 10;
/**
* 1、jdk1.7 公共静态常量和public abstract抽象方法
* 钻火圈
*/
void fire();
/**
* 2、jdk1.8 增加default关键字修饰方法,可以存在方法体,默认权限修饰符为public
* 展示
*/
default void show() {
System.out.println("展示");
}
/**
* 3、jdk1.8 增加static静态方法,默认权限修饰符为public
* 测试
*/
static void test() {
System.out.println("静态方法");
}
}
class ExpandMethodImpl implements IExpandMethod {
@Override
public void fire() {
System.out.println("钻火圈");
}
}
class MyDemo {
public static void main(String[] args) {
IExpandMethod test = new ExpandMethodImpl();
test.fire();
//钻火圈
test.show();
//展示
System.out.println(IExpandMethod.NUMBER);
//10
IExpandMethod.test();
//静态方法
}
}
抽象类与接口的练习
抽象类
package org.westos.demo3;
/**
* @author lwj
* @date 2020/4/20 20:36
*/
public abstract class Animal {
public String name;
public int age;
/**
* 吃饭
*/
public abstract void eat();
/**
* 睡觉
*/
public abstract void sleep();
}
实现类
package org.westos.demo3;
/**
* @author lwj
* @date 2020/4/20 20:38
*/
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫睡觉");
}
}
扩展功能
package org.westos.demo3;
/**
* 扩展功能
* @author lwj
* @date 2020/4/20 20:42
*/
public interface IHighJump {
/**
* 动物跳高
*/
void highJump();
}
加菲猫
package org.westos.demo3;
/**
* 加菲猫
* @author lwj
* @date 2020/4/20 20:40
*/
public class Garfield extends Cat implements IHighJump{
@Override
public void eat() {
System.out.println("加菲猫吃鱼排");
}
@Override
public void sleep() {
System.out.println("加菲猫睡在沙发上");
}
@Override
public void highJump() {
System.out.println("加菲猫学会了跳高");
}
}
狸花猫
package org.westos.demo3;
/**
* 狸花猫
* @author lwj
* @date 2020/4/20 20:44
*/
public class CivetCat extends Cat {
@Override
public void eat() {
System.out.println("狸花猫吃鱼翅");
}
@Override
public void sleep() {
System.out.println("狸花猫睡在摇篮里");
}
public void catchMouse() {
System.out.println("狸花猫抓老鼠");
}
}
测试方法
package org.westos.demo3;
/**
* @author lwj
* @date 2020/4/20 20:46
*/
public class MyTest {
public static void main(String[] args) {
Garfield garfield = new Garfield();
Cat cat = garfield;
cat.name = "波斯猫";
cat.age = 2;
cat.eat();
cat.sleep();
IHighJump jump = garfield;
jump.highJump();
System.out.println("===============");
CivetCat civetCat = new CivetCat();
cat = civetCat;
cat.name = "狸花猫";
cat.age = 3;
cat.eat();
cat.sleep();
CivetCat civetCat1 = (CivetCat) cat;
//执行CivetCat的特有方法,需要向下转型
civetCat1.catchMouse();
}
}
以上是关于10面向对象(抽象类接口)的主要内容,如果未能解决你的问题,请参考以下文章
面向对象--01--类属性方法static代码块抽象类接口内部类
JAVA07 面向对象(高级)类变量类方法代码块final抽象类接口内部类