抽象类和接口
1. 抽象类
1.抽象方法没有方法体,必须存在于抽象类中,均使用abstract关键字修饰
2.抽象类不能直接new对象,必须通过new子类的方式(多态向上转型)创建对象
3.子类必须重写父类中所有的抽象方法,除非子类也是抽象类
4.抽象类中可以书写实例属性,实例方法,构造方法,静态属性,静态方法,静态代码块/普通代码块
5.抽象类实现多态的方式与之前一致
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 9:38
* 抽象类
* 抽象:模糊 不具体
*/
public abstract class Animal {
// 属性 因为当前事物比较抽象 目前暂不描述
private String animalType;
public String getAnimalType() {
return animalType;
}
public void setAnimalType(String animalType) {
this.animalType = animalType;
}
public Animal(String animalType){
this.animalType = animalType;
}
public Animal(){}
public static void main(String[] args) {
}
static{
System.out.println("hello abstract class");
}
{
System.out.println("hello abstract class"); // 每次new子类对象 都会执行一次
}
/**
* 1.抽象方法没有方法体,必须存在于抽象类中,均使用abstract关键字修饰
* 2.抽象类不能直接new对象,必须通过new子类的方式(多态向上转型)创建对象
* 3.子类必须重写父类中所有的抽象方法,除非子类也是抽象类
* 4.抽象类中可以书写实例属性,实例方法,构造方法,静态属性,静态方法,静态代码块/普通代码块
* 5.抽象类实现多态的方式与之前一致
*/
public abstract void eat();
public void print(){
System.out.println("动物介绍");
}
}
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 9:59
*/
public class Tiger extends Animal{
@Override
public void eat() {
System.out.println("老虎吃肉");
}
public void print(){
System.out.println("老虎的个虎介绍");
}
}
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 10:02
*/
public abstract class Pet extends Animal{
public abstract void playWithMaster();
}
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 10:04
*/
public class Dog extends Pet{
@Override
public void playWithMaster() {
System.out.println("狗狗和主人玩耍");
}
@Override
public void eat() {
System.out.println("狗狗吃骨头");
}
public void printDog(){
}
}
package com.atguigu.test1;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 9:58
*/
public class TestAnimal {
public static void main(String[] args) {
// Animal animal = new Animal(); 不能直接new抽象类对象
Tiger tiger = new Tiger(); // 多态向上转型 可以访问子类继承/重写父类的方法 不能访问独有方法
tiger.eat();
Animal dog1 = new Dog();
dog1.eat();
Pet dog2 = new Dog();
dog2.eat();
dog2.playWithMaster();
}
}
2. 抽象类案例
门是一个比较广泛的范围,因为没有明确具体是那种门(防盗门、普通门)
所以此类中门最基本的行为我们无法具体描述,使用abstract修饰
package com.atguigu.test2;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 10:45
* 需求:实现各种门的操作 开门 以及 关门
* 门
*/
public abstract class Door {
private String brand;
private double price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Door() {
}
public Door(String brand, double price) {
this.brand = brand;
this.price = price;
}
public abstract void openDoor();
public abstract void closeDoor();
}
package com.atguigu.test2;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 10:48
*/
public class CommonDoor extends Door{
public CommonDoor() {
}
public CommonDoor(String brand, double price) {
super(brand, price);
}
@Override
public void openDoor() {
System.out.println("普通门开门,插入钥匙,轻轻一转,吱呀一声,门开了");
}
@Override
public void closeDoor() {
System.out.println("普通门关门,duang的一声,门关了");
}
}
package com.atguigu.test2;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 10:47
*/
public class SecurityDoor extends Door{
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public SecurityDoor(String password,String brand,double price){
super(brand,price);
this.password = password;
}
public SecurityDoor(){}
@Override
public void openDoor() {
System.out.println("防盗门开门,输入密码+指纹+钥匙+人脸识别,门开了");
}
@Override
public void closeDoor() {
System.out.println("防盗门关门,自动关门");
}
}
package com.atguigu.test2;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 10:50
* 人类 可以操作门
*/
public class Person {
public void openSecurityDoor(SecurityDoor sd){
sd.openDoor();
}
public void closeSecurityDoor(SecurityDoor sd){
sd.closeDoor();
}
// 如果按照以上的写法 针对普通门依然需要写两个方法 分别用于 开和关
public void open(Door door){
door.openDoor();
}
public void close(Door door){
door.closeDoor();
}
// 书写买门的操作
public Door buyDoor(double money){
if(money >= 2000){
return new SecurityDoor("8956","大金刚",8888);
}else{
return new CommonDoor("小金刚", 1200);
}
}
}
3. final关键字
final 关键字:单词-最终
final使用场景:可以用于修饰属性、方法、类
3.1 final修饰属性
final修饰属性:称之为常量 表示此属性是一个固定的值 其值不能改变 只能被赋值一次
必须在定义的时候赋值 或者 在构造方法中赋值 这两种赋值方式 都是为了保证 我们在使用常量之前 是有具体值的
通常在定义的时候赋值 99%
常量名称全部大写,多个单词之间使用下划线分割 COUNTRY_NAME
package com.atguigu.test3;
import sun.util.resources.cldr.tr.CurrencyNames_tr;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 11:36
* final 关键字:单词-最终
* final使用场景:可以用于修饰属性、方法、类
*
* final修饰属性:称之为常量 表示此属性是一个固定的值 其值不能改变 只能被赋值一次
* 必须在定义的时候赋值 或者 在构造方法中赋值 这两种赋值方式 都是为了保证 我们在使用常量之前 是有具体值的
* 通常在定义的时候赋值 99%
*
* 常量名称全部大写,多个单词之间使用下划线分割 COUNTRY_NAME
*
* final修饰方法,表示此方法可以继承,不能被重写
* final修饰类,此类不能被继承
*/
public class Test1 {
final double PI = 3.14;
final String COUNTRY_NAME;
double radius;
public Test1(){
COUNTRY_NAME = "中国";
}
public Test1(double radius){
this.radius = radius;
COUNTRY_NAME = "中华人民共和国";
}
public static void main(String[] args) {
Test1 test1 = new Test1();
test1.radius = 10;
// test1.pi = 3.24;
System.out.println(test1.PI * test1.radius * test1.radius);
}
}
回顾我们之前使用final修饰常量 发现通常不能被改变的数据 也没有必要存在多份 所以我们可以使用static修饰
public static final 静态常量
全局静态常量是实际开发中使用比较多的 通常在定义的时候直接赋值 或者 在静态代码块中赋值
以上两种方式依然是为了保证使用静态常量之前 是有具体值的
package com.atguigu.test4;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 14:12
* 回顾我们之前使用final修饰常量 发现通常不能被改变的数据 也没有必要存在多份 所以我们可以使用static修饰
*
* public static final 静态常量
* 全局静态常量是实际开发中使用比较多的 通常在定义的时候直接赋值 或者 在静态代码块中赋值
* 以上两种方式依然是为了保证使用静态常量之前 是有具体值的
*/
public class Test1 {
public static final double PI = 3.14;
public static final String COUNTRY_NAME;
static{
COUNTRY_NAME = "中国";
}
}
3.2 final修饰方法
final修饰的方法 不能被重写 可以被继承
package com.atguigu.test4;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 14:16
*
* final修饰的方法 不能被重写 可以被继承
*/
public class A {
public final void m1(){
System.out.println("A类m1方法");
}
public void m2(){
System.out.println("A类m2方法");
}
public void m3(){
System.out.println("A类m3方法");
}
public static void main(String[] args) {
B b = new B();
b.m1();
}
}
class B extends A{
public void m1(){ // 此处编译错误
}
public void m3(){
}
}
3.3 final修饰类
被final修饰的类 不能被继承 因为继承意味着改变
package com.atguigu.test4;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 14:18
*/
public final class C {
}
//class D extends C{ 被final修饰的类 不能被继承 因为继承意味着改变
//}
4. 接口
1.接口中的方法 默认都是全局 抽象 方法 不管是否书写 都将使用public abstract修饰
2.接口不能直接new对象,必须通过new实现类(子类)的方式来创建对象(多态向上转型)
3.实现类(子类)必须实现(重写)接口中所有的抽象方法 除非实现类也是抽象类 或者 接口
4.接口不能书写普通属性(默认都是全局静态常量 不管是否书写均使用 public static final 修饰)、构造方法、普通方法、静态方法(JDK1.7-)
5.一个类只能继承一个父类,但是可以实现多个接口
6.接口实现多态的方式与之前一致
JDK1.8 可以书写普通方法 在返回值之前加上default关键字 静态方法
面试题:Java支持多继承吗?
不支持,但是可以通过接口继承多个接口的方式,实现类似多继承的效果
package com.atguigu.test6;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 14:51
* 接口相当于一种约定,只关注约定,不关注具体实现
*
* Java中的接口使用interface来修饰 UI User Interface
*/
public interface USB {
int NUM = 10;
// public USB(){
//
// }
/**
* 1.接口中的方法 默认都是全局 抽象 方法 不管是否书写 都将使用public abstract修饰
* 2.接口不能直接new对象,必须通过new实现类(子类)的方式来创建对象(多态向上转型)
* 3.实现类(子类)必须实现(重写)接口中所有的抽象方法 除非实现类也是抽象类 或者 接口
* 4.接口不能书写普通属性(默认都是全局静态常量 不管是否书写均使用 public static final 修饰)、构造方法、普通方法、静态方法(JDK1.7-)
* 5.一个类只能继承一个父类,但是可以实现多个接口
* 6.接口实现多态的方式与之前一致
*
* JDK1.8 可以书写普通方法 在返回值之前加上default关键字 静态方法
*
* 面试题:Java支持多继承吗?
* 不支持,但是可以通过接口继承多个接口的方式,实现类似多继承的效果
*/
void connect();
public default void m1(){
}
public static void m2(){
}
}
package com.atguigu.test6;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 15:00
*/
public class Mouse implements USB{
@Override
public void connect() {
System.out.println("鼠标链接上USB接口,可以点击世界了");
}
}
package com.atguigu.test6;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 15:02
*/
public abstract class Convert implements USB{
public abstract void convert();
}
package com.atguigu.test6;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 15:03
*/
public class HuaWei extends Convert{
@Override
public void convert() {
System.out.println("网线链接华为转换器");
}
@Override
public void connect() {
System.out.println("转换器连接USB接口");
}
}
package com.atguigu.test6;
/**
* @author WHD
* @description TODO
* @date 2022/7/20 15:01
*/
public class TestUSB {
public static void main(String[] args) {
// USB usb = new USB();
USB mouse = new Mouse(); // 多态向上转型
mouse.connect();
}
}