day13复习
Java-day14学习笔记
一、抽象类
比如我现在说一个动物,大家肯定不知道是什么动物。但是我要是指着一个猫说,这是一个动物,指着一条狗说,这是一个动物,这都是没问题的。这说明动物是一个抽象的概念,只有猫和狗才是具体的概念。而刚才说的动物是将某些事物的共同特征给抽取或者抽象出来组成的,这种被抽象出来的内容被我们称为抽象类。再想想我们写过的eat和sleep,我们之前对吃和睡都是统一定义的,但是很明显每个人吃的饭和睡觉的方式都是不一样的,所以不能进行统一的定义。我们只需要声明一下吃和睡的方法即可,方法的内容我们不需要定义。像这种只有方法声明,而没有方法体的方法被称作抽象方法。
1.1 格式
关键字: abstract
抽象类:
public abstract class 类名{
}
抽象方法:
public abstract 返回值类型 方法名(参数列表);
//抽象类
public abstract class A {
//抽象方法
public abstract void eat();
}
1.2 注意事项
1. 抽象类中可以放抽象方法
2. 抽象方法必须放在抽象类中
3. 抽象类不能被实例化(也就是不能被创建对象)
4. 抽象类可以被继承
1.3 抽象类中的成员
变量:
可以放普通的成员变量、静态的变量、常量
方法:
可以放抽象方法,也可以放非抽象方法
构造方法:
有构造方法,但是不能进行实例化(也就是不能创建对象)
为什么有构造方法?
因为抽象类可以被继承,同时类中也有成员,所以需要用构造方法进行初始化
怎么样进行实例化?
可以通过抽象类的子类进行实例化
/*
抽象的C类
*/
abstract class C {
//变量
int i; //普通的成员变量
static int j; //静态的成员变量
//方法
public abstract void a(); //抽象方法
public void b(){ //非抽象方法
}
public static void c(){ //静态方法
}
//构造方法
// public C(){
//
// }
}
public class Demo2 {
public static void main(String[] args) {
// C c = new C(); //报错,不能实例化
}
}
某公司中有如下员工分类:
开发工程师 属性(姓名、年龄、工资、奖金) 行为(工作:敲代码)
测试工程师 属性(姓名、年龄、工资) 行为(工作:找BUG)
产品经理 属性(姓名、年龄、工资、奖金) 行为(工作:控制进度)
请用继承和多态完成如上代码,并测试
/*
某公司中有如下员工分类:
开发工程师 属性(姓名、年龄、工资、奖金) 行为(工作:敲代码)
测试工程师 属性(姓名、年龄、工资) 行为(工作:找BUG)
产品经理 属性(姓名、年龄、工资、奖金) 行为(工作:控制进度)
请用继承和多态完成如上代码,并测试
*/
/*
员工类
*/
abstract class Employee {
String name;
int age;
int salary;
public abstract void work();
public void show(){
System.out.println(name + "---" + age + "---" + salary);
}
}
/*
开发工程师
*/
class JavaDeveloper extends Employee {
int bonus;
public JavaDeveloper(String name, int age, int salary, int bonus){
this.name = name;
this.age = age;
this.salary = salary;
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("写代码");
}
public void show(){
super.show();
System.out.println(bonus);
}
}
/*
测试工程师
*/
class TestDeveloper extends Employee {
public TestDeveloper(String name, int age, int salary){
this.name = name;
this.age = age;
this.salary = salary;
}
@Override
public void work() {
System.out.println("找Bug");
}
}
/*
产品经理类
*/
class ProjectManager extends Employee {
int bonus;
public ProjectManager(String name, int age, int salary, int bonus){
this.name = name;
this.age = age;
this.salary = salary;
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("控制项目进度");
}
}
public class Test {
public static void main(String[] args) {
JavaDeveloper jd = new JavaDeveloper("雷军", 40, 1000, 100000000);
jd.work();
jd.show();
TestDeveloper td = new TestDeveloper("Jack Ma", 43, 1);
td.work();
td.show();
}
}
二、final关键字
final可以修饰类、方法、变量
修饰类:
类不能被继承
修饰方法:
方法不能被重写
修饰变量:
变量变为了常量,而常量需要进行初始化
初始化的方式:
1. 在声明的同时直接进行初始化【推荐】
2. 在构造方法中进行初始化
3. 在构造代码块中进行初始化
三、接口
接口就是一组规范。
之前我们写的案例中的猫和狗,都会吃会睡,属于废狗、废猫。但是现在有一些狗经过了特种培训,可以开车了,这种就是特种狗。这种技能很特殊,一般狗不会,那么就不应该将这种技能应用在所有狗身上。而只是需要让培训过的狗掌握即可(也就是在公共的技能上的附加功能),这个时候我们就可以用接口来解决。
3.1 格式
关键字: interface
格式:
修饰符 interface 接口名 {
}
注意:接口经过编译后也会生成 .class文件
3.2 注意事项
1. 接口不能进行初始化(也就是不能创建对象)
3.3 接口中的成员
变量
接口中的变量都是常量,默认都被public static final修饰
方法
接口中的方法,默认都被public abstract修饰
构造方法
接口中没有构造方法。
为什么接口中没有构造方法?
因为接口的变量都是静态的,方法默认都是抽象的,所以不需要进行初始化
那么接口如何进行实例化呢?(也就是创建对象)
可以通过接口的实现类来完成实例化
关键字:implements
class 实现类 implements 接口名 {
}
练习:
改进原来的猫狗案例,其中狗变成超狗会开车了。(测试中有普通狗、普通猫和超狗)
//抽象动物类
abstract class Animal {
String name;
int age;
public abstract void eat();
public abstract void sleep();
}
//接口:用来扩展功能(谁用谁实现)
interface AnimalTrain {
public abstract void driveCar();
}
//猫类
class Cat extends Animal {
public Cat(String name, int age){
this.name = name;
this.age = age;
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫趴着睡觉");
}
}
//狗类
class Dog extends Animal {
public Dog(String name, int age){
this.name = name;
this.age = age;
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
@Override
public void sleep() {
System.out.println("狗站着睡觉");
}
}
class SuperDog extends Animal implements AnimalTrain {
public SuperDog(String name, int age){
this.name = name;
this.age = age;
}
@Override
public void eat() {
System.out.println("超狗吃战斧牛排");
}
@Override
public void sleep() {
System.out.println("超狗睡1000平米的床");
}
@Override
public void driveCar() {
System.out.println("超狗会开车");
}
}
public class Demo4 {
public static void main(String[] args) {
//正常模式
// SuperDog sd = new SuperDog("旺财", 3);
// sd.driveCar();
//多态模式;抽象类
// Animal a = new SuperDog("旺财", 3);
// SuperDog aa = (SuperDog)a; //向下转型
// aa.driveCar();
//多态模式:接口
AnimalTrain b = new SuperDog("旺财", 3);
}
}
3.4 类与类、类与接口、接口与接口之间的关系
类与类:
1. 可以单继承
2. 不可以多继承
为什么不能多继承?
如果一个类有多个父类的话,万一这些父类中有声明相同的方法,那么子类就不知道要使用哪个方法了。所以不能多继承。
3. 可以多层继承(继承体系)
类与接口:
1. 可以单实现
2. 也可以多实现
为什么可以多实现?
因为接口中的方法默认都是抽象的,是没有方法体的,是都要被子类重写才能使用的。就算多实现的这些接口有声明相同的方法,那么也必须要在子类中重写(多个声明相同的方法只能有一个重写)才能使用。所以可以多实现。
接口与接口:
1. 可以多继承
注意:一个普通类可以在继承一个类的同时,多实现接口(一定要先继承再实现)
3.5 实现多态的三种方式
普通类 【几乎不用】
抽象类 【很少用】
接口 【很常用】