抽象类
(01)抽象类:被abstract
关键字修饰类。
理解:用来表示现实生活中抽象的【图纸】或【模板】。
比如,动物类就是一个抽象类,是一个广泛的概念。不像猫、狗、猪有具体的概念。
(02)成员变量:概念和具体类中一样。
(03)成员方法:概念和具体类中一样。
(04)构造方法:概念和具体类中一样。
(05)抽象方法:被abstract
关键字修饰、没有方法体的方法。
方法体就是大括号{}
里的内容。
如下图所示,在抽象类中定义了一个含有方法体的抽象方法会报错。
抽象类完整示例:
public abstract class Animal {
private String name;//抽象类的成员变量
private Integer age;//抽象类的成员变量
//抽象类的无参构造方法
public Animal() {
}
//抽象类的有参构造方法
public Animal(String name, Integer age) {
this.name = name;
this.age = age;
}
//抽象类的抽象方法
public abstract void eat();
}
(06)抽象类中有构造方法、但是不能创建对象。
原因:抽象类是一个抽象的概念,比如一个“图形类”,就是一个抽象概念,不像长方形类、圆形类可以确定成员变量。
疑问:抽象类写完了、却不能创建对象、那抽象类有什么用?答:继承。
可能遇到的面试题:
- 抽象类中的方法可以有方法体吗?
答:可以有。首先,没有方法体的方法是被abstract修饰的抽象方法,不被abstract修饰的都可以有方法体。其次,抽象类中不是只可以定义抽象方法,也可以定义普通方法,普通方法可以有方法体。如下图所示:
- 抽象类中有构造方法吗?如果有可以创建对象吗?
答:有构造方法,但是不能创建对象
。抽象类不能创建对象,其创建对象没有意义,但是抽象类可以保存一类事物具备的共同属性和行为,让子类进行继承。抽象类的构造方法不是给自己用的,而是为了让子类调用构造方法创建对象时初始化用的。
(07)继承:子类通过**extends**关键字继承父类、父类中的所有成员子类都会自动继承下来。
// 父类
public abstract class A {
int x = 100;
public void m() {
System.out.println(200);
}
}
// 类B继承类A
// 子类
public class B extends A {
public static void main(String[] args) {
A a = new A();
System.out.println(a.x);
a.m();
B b = new B();
System.out.println(b.x);
b.m();//m方法没有返回值,所以直接对象.调用就好
}
}
具体类 可以继承 具体类
具体类 可以继承 抽象类 最常用
抽象类 可以继承 具体类
抽象类 可以继承 抽象类
(08)抽象类就是为了继承
原因:抽象类父类负责设计、具体类子类负责实现。
思想:先设计、再实现。
public abstract class Calculate {
public abstract int add1(int a,int b);
public abstract int add2(int a,int b);
public abstract int add3(int a,int b);
}
public class addExtend extends Calculate{
@Override
public int add1(int a, int b) {
return a+b;
}
@Override
public int add2(int a, int b) {
return a-b;
}
@Override
public int add3(int a, int b) {
return a*b;
}
}
(09)创建对象的语法句式
类名 变量 = new 类构造方法
父类 变量 = new 子类构造方法
public abstract class Car {
public abstract void driver();
}
public class BMW extends Car{
@Override
public void driver() {
System.out.println("驾驶宝马汽车");
}
public static void main(String[] args) {
BMW bmw = new BMW();
bmw.driver();
Car bmw2 = new BMW();
bmw2.driver();
}
}
(10)继承体系中父类子类之间的类型转换
子类型赋值给父类型没问题(向上转型)
public class Audi extends Car{
public static void main(String[] args) {
Audi audi = new Audi();
Car audi2 = audi;//子类型赋值给父类型没问题
audi2.driver();
}
}
父类型赋值给子类型需要强制类型转换(向下转型)
public class Audi extends Car{
public static void main(String[] args) {
Car audi = new Audi();
Audi audi1 = (Audi) audi;//父类型赋值给子类型需要强制类型转换
audi1.driver();
}
}
(11)static静态关键字
前提条件:能够区别类和对象。
被static修饰的属于类、通过"类名.成员"的方式来调用。
public class E {
static int a = 2;
static void m1(){
System.out.println(3);
}
public static void main(String[] args) {
System.out.println(E.a);
E.m1();
}
}
不被static修饰的属于对象、 通过"对象.成员"的方式来调用
public class E { int b = 5; void m2(){ System.out.println(8); } public static void main(String[] args) { E e = new E(); System.out.println(e.b); e.m2(); }}
静态成员可以被所有对象共享使用。(不推荐)
(12)可见性修饰符:4个范围3个关键字
private 私有的 当前类
默认的 当前类+包
protected 保护的 当前类+包+外包子类
public 公共的 都可见
public abstract class Person { String name; int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public abstract void m1(int a, double b); public abstract boolean m2(char c, int[] d);}
抽象类习题
第一题考点:抽象类、继承
创建长5宽3长方形对象、求周长、求面积。
创建半径4圆对象、求周长、求面积。
解析:需要创建一个图形的抽象类,这个抽象类中的成员变量要适用于所有的图形,所以不能把单独的图形的成员变量放在抽象类中。
//抽象图形类:所有图形的父类public abstract class TuXing { //成员变量:所有子类都有的属性 //求图形周长方法 public abstract void m1(); //求图形面积方法 public abstract void m2();}
public class ChangFangXing extends TuXing{ Integer length; Integer width; public ChangFangXing() { } public ChangFangXing(Integer length, Integer width) { this.length = length; this.width = width; } public Integer getLength() { return length; } public void setLength(Integer length) { this.length = length; } public Integer getWidth() { return width; } public void setWidth(Integer width) { this.width = width; } @Override public String toString() { return "ChangFangXing{" + "length=" + length + ", width=" + width + '}'; } @Override public void m1() { System.out.println(2*(width+length)); } @Override public void m2() { System.out.println(width*length); }}public static void main(String[] args) { ChangFangXing changFangXing = new ChangFangXing(9,2); changFangXing.m1(); changFangXing.m2(); }
第二题考点:抽象类、继承、数组
解析:根据合同员工和计时员工可以知道,员工的名字是员工类的公共变量
创建员工抽象类:
public abstract class Employees { String name; public Employees() { } public Employees(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public abstract int getTotalWage();//获得工资的方法 @Override public String toString() { return "Employees{" + "name='" + name + '\'' + '}'; }}
(1)创建合同员工(名字、工资)
Emp e1 = new Emp(“张三”, 3000);
Emp e2 = new Emp(“李四”, 4000);
public class Emp extends Employees{
Integer wage;
public Emp() {
}
@Override
public int getTotalWage() {
return wage;
}
public Emp(Integer wage) {
this.wage = wage;
}
public Emp(String name, Integer wage) {
super(name);
this.wage = wage;
}
public Integer getWage() {
return wage;
}
public void setWage(Integer wage) {
this.wage = wage;
}
@Override
public String toString() {
return "Emp{" +
"wage=" + wage +
", name='" + name + '\'' +
'}';
}
}
(2)创建计时员工(名字、工时、工时费)
Mem m1 = new Mem(“小王”, 50, 100);
Mem m2 = new Mem(“小李”, 50, 70);
public class Mem extends Employees{
Integer hour;
Integer hourWage;
public Mem() {
}
@Override
public int getTotalWage() {
return hour*hourWage;
}
public Mem(Integer hour, Integer hourWage) {
this.hour = hour;
this.hourWage = hourWage;
}
public Mem(String name, Integer hour, Integer hourWage) {
super(name);
this.hour = hour;
this.hourWage = hourWage;
}
public Integer getHour() {
return hour;
}
public void setHour(Integer hour) {
this.hour = hour;
}
public Integer getHourWage() {
return hourWage;
}
public void setHourWage(Integer hourWage) {
this.hourWage = hourWage;
}
@Override
public String toString() {
return "Mem{" +
"name='" + name + '\'' +
", hour=" + hour +
", hourWage=" + hourWage +
'}';
}
}
(3)把4个员工对象添加到员工数组中?
public static void main(String[] args) {
Emp emp1 = new Emp("张三", 3000);
Emp emp2 = new Emp("李四", 4000);
Mem mem1 = new Mem("小王", 50, 100);
Mem mem2 = new Mem("小李", 50, 70);
Employees[] arr = {emp1,emp2,mem1,mem2};
}
(4)求员工数组中所有员工的工资是多少?
①在父类中定义一个计算工资的抽象方法,每个员工类必须实现这个方法
public abstract int getTotalWage();//获得工资的方法
②在每个员工的具体类中实现父类的方法
@Override
public int getTotalWage() {
return wage;
}
@Override
public int getTotalWage() {
return hour*hourWage;
}
③测试求员工数组中所有员工的工资
public static void main(String[] args) {
Emp emp1 = new Emp("张三", 3000);
Emp emp2 = new Emp("李四", 4000);
Mem mem1 = new Mem("小王", 50, 100);
Mem mem2 = new Mem("小李", 50, 70);
Employees[] arr = {emp1,emp2,mem1,mem2};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i].getTotalWage();//调用方法
}
System.out.println(sum);
}