目录
1. 抽象方法
1、抽象:抽取像的、相同的、相似的内容出来
2、抽象方法:只有方法声明,而没有方法实现的方法,就是抽象方法 在各个子类中,对于某个方法都有自己不同的实现,所以实现各不相同,无法抽取,只能抽取方法的声明上来,在父类中,方法就只有方法声明没有方法体。就是抽象方法。
3、定义格式:
- 没有方法实现,连大括号都没有,直接在方法声明后面加上一个分号,表示方法定义结束
- 为了将方法标记为抽象方法,需要在方法前面加上一个abstract关键字
代码示例:
abstract class Animal2 {
//抽象方法
public abstract void eat();
}
class Dog2 extends Animal2 {
public void eat() {
System.out.println("狗吃肉");
}
}
2. 抽象类
1、可以定义抽象方法的类,就是抽象类
2、定义格式:
abstract class 类名 {
}
代码示例:
public class Simple01 {
public static void main(String[] args) {
System.out.println("Hello World!");
}
//抽象类
abstract class Animal {
public abstract void eat();
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
2.1 抽象类的特点
1、抽象类和抽象方法都需要使用abstract关键字修饰 抽象类:abstract class {} 抽象方法:public abstract void test();
2、抽象类和抽象方法的关系: 抽象方法所在的类必须是抽象类 抽象类中未必一定都定义抽象方法,抽象类中未必存在抽象方法
3、抽象类的实例化(抽象类如何创建对象) 抽象类不能直接实例化 定义抽象类的子类,由子类创建对象,调用方法
4、抽象类子类的前途 在子类中,将父类所有的抽象方法全部重写(实现),子类就成了一个普通类,就可以创建对象 在子类中,没有将父类中所有的抽象方法全部实现,子类就还是一个抽象类,还需要使用abstract关键字修饰子类。
2.2 抽象类成员特点
1、成员变量:可以定义变量,也可以定义常量,但是不能被抽象
2、构造方法:有 虽然本类型无法创建对象,但是抽象类一定有子类,子类会访问父类的抽象方法。 是否有构造方法,不取决于是否可以创建对象,而是取决于是否可以定义成员变量。如果可以定义成员变量,那么就需要初始化成员变量,就是构造方法来完成的。
3、成员方法: 既可以是抽象方法:强制子类重写 也可以是非抽象方法:用于给子类继承,提高代码的复用性
代码示例:
/**
* 抽象类成员特点
*/
public class Simple03 {
public static void main(String[] args) {
Fu f = new Zi();
f.test();
}
}
abstract class Fu {
int i = 10;
final int j = 20;
//abstract final int j = 20; //常量,不能被抽象
//abstract int i = 10;// //变量,不能被抽象
public abstract void test();
public Fu() {
i = 100;
}
}
class Zi extends Fu {
@Override
public void test() {
System.out.println("Zi:" + i);
}
}
3. 接口
3.1 接口的概述
1、广义:一切定义规则的都是接口
2、狭义:java中用于定义方法命名的规则就是接口。Java接口中,全都是方法的声明,都是抽象方法
3、好处:一旦将命名规则定义出来,【方法的调用】和【方法的实现】就分离开了,可以提升开发效率,降低代码的耦合性
3.2 接口的特点
1、接口的定义:使用interface关键字,编译也是生成一个【.class】文件 interface 接口名称 { 方法声明的定义; }
2、接口中,只可以声明抽象方法(只能定义方法起名字的规则)
3、类可以实现接口:使用implements关键字 实现:接口中只有方法名称的定义,在类中把接口方法的真正完成逻辑写出来 class 类名称 implements 接口名称 { 对接口中方法的实现; }
4、接口的实例化:不能直接实例化 定义实现类,实现接口,类创建对象,对象调用方法
5、接口的实现类前途: 实现类如果是一个抽象类,那么该类没有实现接口中的所有抽象方法 实现类如果是一个普通类,那么该类实现了接口中的所有抽象方法
代码示例:
public class Simple01 {
public static void main(String[] args) {
//MyInterImplA miia = new MyInterImplA();
MyInterImplB miib = new MyInterImplB();
miib.test1();
}
}
interface MyInterA {
public abstract void test1();
}
class MyInterImplB implements MyInterA {
@Override
public void test1() {
System.out.println("MyImplB");
}
}
abstract class MyInterImplA implements MyInterA {
}
class MyTest extends MyInterImplA{
@Override
public void test1() {
}
}
3.3 接口中成员的特点
1、成员变量: 只能是常量,不能是变量 默认加上public static final 建议手动加上 ,因为常量是存在方法区的常量池中,没在对象中
2、构造方法: 没有构造方法。接口中无法定义成员变量,所以不需要使用构造方法给成员变量初始化赋值。 虽然接口有自己的实现类,但是对于实现类而言,不去访问接口中的构造方法,而是访问实现类的父类的构造方法。(父类是亲爹、接口是干爹,找亲爹的构造方法,而不是干爹的)
3、成员方法: 只能是抽象方法,不能是非抽象方法 默认加上public abstract, 建议手动加上,不加public abstract 的方法也是抽象方法
代码示例:
/**
* 接口中成员的特点
*/
public class Simple02 {
public static void main(String[] args) {
System.out.println(MyInterB.a);
//MyInterB.a = 20;
}
}
interface MyInterB {
public static final int a = 10;
public abstract void test();
}
abstract class MyImplB implements MyInterB {
//实现类中不可以修改 接口中的a
}
4. 类与类、类与接口、接口与接口之间的关系
1、类与类 继承的关系,使用extends 可以单继承、不可以多继承、可以多层继承
2、类与接口: 实现关系,使用implements 可以单实现、也可以多实现 多实现的格式: class 实现类类名 implements 接口1, 接口2, 接口3.......{ 重写所有接口中的所有抽象方法 } 多实现没有安全隐患:即使两个接口中有一样的方法声明,但是在类中也只有一个实现 也就是不需要像c#那样的显示调用。不影响,重复就重复 在继承一个父类的前提下,还可以实现多个接口 格式: class 子类类名 extends 父类类名 implements 接口1, 接口2.....{ //重写父类和所有接口中的所有抽象方法 }
3、接口与接口: 继承关系,使用extends 可以单继承、也可以多继承、可以多层继承 多继承的格式: interface 接口名 extends 父接口1, 父接口2.....{ 相当于继承了所有父接口的所有抽象方法 }
4、类和接口的区别(设计区别): 抽象类:定义物体本身具有的固有属性和行为 接口:定义物体通过学习、训练而扩展出来的行为
代码示例:
public class Simple03 {
public static void main(String[] args) {
MyImpl12 mi12 = new MyImpl12();
mi12.test1();
MyImpl3 m3 = new MyImpl3();
m3.test1();
m3.test2();
m3.test3();
m3.test4();
}
}
interface MyInter1 {
public abstract void test1();
public abstract void test2();
}
interface MyInter2 {
public abstract void test1();
public abstract void test3();
}
interface MyInter3 {
public abstract void test4();
}
interface MyInter4 extends MyInter1, MyInter2, MyInter3 {
}
class MyImpl12 implements MyInter1, MyInter2 {
public void test1() {
System.out.println("test1");
}
public void test2() {
System.out.println("test2");
}
public void test3() {
System.out.println("test3");
}
}
class MyImpl3 extends MyImpl12 implements MyInter3 {
public void test4() {
System.out.println("test4");
}
}