抽象类
概述
动物本身并不是一个具体的事物,而是一个抽象的事物。只有真正的猫,狗才是具体的动物。
不同的动物吃的东西应该是不一样的,所以,我们不应该在动物类中给出具体体现,而是给出一个声明即可。
在Java中,一个没有方法体的方法应该定义为抽象方法,类中有抽象方法的类被称为抽象类,用abstract修饰
格式
//抽象类
abstract class 类名{}
//抽象方法
public abstract 返回值类型 方法名();
特点:
- 抽象类和抽象方法必须用abstract关键字修饰
- 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
- 抽象类中可以有构造方法,但抽象类不能进行实例化,构造方法是为了在子类创建对象时对父类数据进行初始化
- 可以按照多态的方式,由父类引用指向子类对象
- 抽象类的子类要么是抽象类,要么重写抽象类中的所有抽象方法
abstract class Animal
{
public abstract void eat();
public void sleep()
{
System.out.println("sleep...");
}
}
class Dog extends Animal
{
@Override
public void eat() {
System.out.println("dog eat...");
}
}
class Cat extends Animal
{
@Override
public void eat() {
System.out.println("cat eat...");
}
}
public class Demo4 {
public static void main(String[] args) {
Animal a = new Dog();
a.sleep();
a.eat();
}
}
抽象类的成员方法特性:
抽象方法:强制要求子类覆盖
非抽象方法:子类继承,提高代码的复用性
一个类如果没有抽象方法,可不可以定义为抽象类?
可以,这样做唯一的意义就是该类无法创建对象
abstract不能和哪些关键字共存
- private:被private修饰的方法不能被继承,但是abstract强制要求子类重写,子类无法继承该方法,所以无法重写该方法。
- final:被final修饰的方法不能被重写,但是abstract强制要求子类重写。
- static:被static修饰的方法属于类,不存在重写
接口
在现实生活中,某些特定事物具有一些特殊功能,比如有一部分狗经过训练后可以成为导盲犬,但不是所有狗都可以具备这个功能,把这样的功能定义到Dog类中并不合适。
为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现
特点:
- 接口用关键字interface表示,类实现接口用implements表示
- 接口不能实例化
- 如果类实现接口,要么重写接口中的所有方法,要么定义为抽象类,只实现部分方法,但这样做意义不大
格式:
//定义
interface 接口名{}
//实现
class 类名 implements 接口名{}
接口成员的特点:
- 成员变量只能是常量,而且是静态
- 接口没有构造方法
- 成员方法只能是抽象方法
class Dog
{
public void eat()
{
System.out.println("dog eat...");
}
public void sleep()
{
System.out.println("dog sleep...");
}
}
class GuideDog extends Dog implements Train
{
@Override
public void guide() {
System.out.println("guide...");
}
}
interface Train
{
public static final int YEAR = 2;//训练的时间
public abstract void guide();//训练方法
}
class Demo
{
public static void main(String[] args)
{
GuideDog g=new GuideDog();
g.sleep();
g.eat();
g.guide();
System.out.println(g.YEAR);
}
}
/*
在接口中,成员变量的修饰符public、static、final是默认的
成员方法的修饰符public、abstract也是默认的
即不写也会默认加上
*/
类与类的关系:类与类之间是继承关系,只能单继承,不能多继承,但可以多层继承。
类与接口的关系:类与接口之间是实现关系,可以单实现,也可以多实现。并且在继承一个类的同时可以实现多个接口。
class AA{}
interface B{}
interface C{}
class DD extends AA implements B,C{}
接口与接口的关系:接口与接口之间是继承关系,可以单继承,也可以多继承。
interface AA{}
interface BB{}
interface CC extends AA,BB{}
抽象类与接口的区别
- 抽象类的成员变量可以是常量也可以是变量,接口的成员变量只能是常量
- 抽象类有构造方法,接口无构造方法
- 抽象类的成员方法可以抽象也可以非抽象,接口的成员方法只能是抽象的
- 抽象类被继承体现的是“is a”的关系,类中定义的是该继承体系的共性功能
接口被实现体现的是“like a”的关系,接口中定义的是该继承体系的扩展功能。
JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用
interface AA
{
public default void show()
{
System.out.println("show...")
}
}
抽象类名和接口名作为形参
抽象类名作为形参
//当方法的形参是抽象类名时,需要传入该抽象类的子类对象
public class Test {
public static void main(String[] args) {
BB b=new BB();
show(b);
}
public static void show(AA a)
{
a.test();
}
}
abstract class AA
{
abstract public void test();
}
class BB extends AA
{
@Override
public void test() {
System.out.println("test...");
}
}
接口名作为形参
//当方法的形参是接口名时,需要传入实现该接口的类的对象
public class Test {
public static void main(String[] args) {
BB b=new BB();
show(b);
}
public static void show(AA a)
{
a.test();
}
}
interface AA
{
abstract public void test();
}
class BB extends AA
{
@Override
public void test() {
System.out.println("test...");
}
}
抽象类名和接口名作为返回值类型
抽象类名作为返回值类型
//当方法的返回值类型为一个抽象类时,需要返回该抽象类的子类对象
public class Test {
public static void main(String[] args) {
AA a=show();
a.test();
}
public static AA show()
{
BB b = new BB();
return b;
}
}
abstract class AA
{
public abstract void test();
}
class BB extends AA
{
@Override
public void test() {
System.out.println("test...");
}
}
接口名作为返回值类型
//当方法的返回值类型为一个接口时,需要返回实现该接口的类的对象
public class Test3 {
public static void main(String[] args) {
AA a=show();
a.test();
}
public static AA show()
{
BB b = new BB();
return b;
}
}
interface AA
{
public abstract void test();
}
class BB implements AA
{
@Override
public void test() {
System.out.println("test...");
}
}
链式编程
个人理解:链式编程就是在对象调用方法时,这个方法会返回一个对象,然后就可以继续调用其他的方法,从而形成像一条链条一样的的形式一直调用下去,当然前提是每次调用都会返回对象。
public class Test3 {
public static void main(String[] args) {
Student student=new Student();
Student student1=student.getStudent(student,14);
int a1=student1.show().age;
int a2=new Student().getStudent(new Student(),14).show().age;
System.out.println(a1);
System.out.println(a2);
}
}
class Student
{
int age=20;
public Student getStudent(Student student,int age)
{
student.age=age;
return new Student();
}
public Student show()
{
return this;
}
}
来源:CSDN
作者:weixin_45919908
链接:https://blog.csdn.net/weixin_45919908/article/details/103656239