标签 JAVA基础 下的文章

接口 interface

java提供了一个关键词interface 用这个关键词来定义接口这种特殊结构
public interface 接口名(){
  //成员变量(常量)
  //public static final String NAME="张三"
  //public static final 不加 java自动帮你加上
   String NAME="张三";
  //成员方法(抽象方法)
  //public abstract 不加 java 自动帮你加上
  void test1();
}
接口的常量可以通过接口名.常量名

接口的好处

弥补了类单继承的不足,一个类同时可以实现多个接口。
让程序可以面向接口编程,这样程序员可以灵活方便的切换各种业务实现。

接口使用场景

对象有什么?

比如:

我有车

我有房

我有钱

....

JDK8接口的新特性

随着JDK版本的升级,在JDK8版本以后接口中能够定义的成员也做了一些更新,从JDK8开始,接口中新增的三种方法形式。

我们看一下这三种方法分别有什么特点?

默认方法:必须使用default修饰,默认会被public修饰 实例方法:对象的方法,必须使用实现类的对象来访问。私有方法:必须使用private修饰。(JDK 9开始才支持的) 实例方法:对象的方法。

静态方法:必须使用static修饰,默认会被public修饰

public interface A {
    /**
     * 1、默认方法:必须使用default修饰,默认会被public修饰
     * 实例方法:对象的方法,必须使用实现类的对象来访问。
     */
    default void test1(){
        System.out.println("===默认方法==");
        test2();
    }

    /**
     * 2、私有方法:必须使用private修饰。(JDK 9开始才支持的)
     *   实例方法:对象的方法。
     */
    private void test2(){
        System.out.println("===私有方法==");
    }

    /**
     * 3、静态方法:必须使用static修饰,默认会被public修饰
     */
     static void test3(){
        System.out.println("==静态方法==");
     }

     void test4();
     void test5();
     default void test6(){

     }
}
接下来我们写一个B类,实现A接口。B类作为A接口的实现类,只需要重写抽象方法就可以了,对于默认方法不需要子类重写。

代码如下:

public class B implements A{
    @Override
    public void test4() {

    }

    @Override
    public void test5() {

    }
}
最后,写一个测试类,观察接口中的三种方法,是如何调用的
public class Test {
    public static void main(String[] args) {
        // 目标:掌握接口新增的三种方法形式
        B b = new B();
        b.test1();    //默认方法使用对象调用
        // b.test2();    //A接口中的私有方法,B类调用不了
        A.test3();    //静态方法,使用接口名调用
    }
}
综上所述:JDK8对接口新增的特性,有利于对程序进行扩展。

接口的其他细节

一个接口可以继承多个接口
public class Test {
    public static void main(String[] args) {
        // 目标:理解接口的多继承。
    }
}

interface A{
    void test1();
}
interface B{
    void test2();
}
interface C{}

//比如:D接口继承C、B、A
interface D extends C, B, A{

}

//E类在实现D接口时,必须重写D接口、以及其父类中的所有抽象方法。
class E implements D{
    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }
}
接口除了上面的多继承特点之外,在多实现、继承和实现并存时,有可能出现方法名冲突的问题,需要了解怎么解决(仅仅只是了解一下,实际上工作中几乎不会出现这种情况)
1.一个接口继承多个接口,如果多个接口中存在方法声明冲突,则此时不支持多继承
2.一个类实现多个接口,如果多个接口中存在方法声明冲突,则此时不支持多实现
3.一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会有限使用父类的方法
4.一个类实现类多个接口,多个接口中有同名的默认方法,则这个类必须重写该方法。
综上所述:一个接口可以继承多个接口,接口同时也可以被类实现。

abstract 抽象

Java关键字abstract,它是抽象的意思,可以修饰类也可以修饰方法

被abstract修饰的类,就是抽象类

被abstract修饰的方法,就是抽象方法(不允许有方法体)

抽象类不能被创建出来也就是不能被new出来

抽象方法只能在抽象类中创建

案例

/**
 * @author TongHui
 * @date 2021.04.05 14:23
 */
public abstract class Animal {
    private String name;
    private int age;


    //动物能叫?
    //抽象方法不是先方法
    //抽象方法只能在抽象类中定义
    //抽象的好处抽象类中有些方法不适合实现
    public abstract void say();

    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;
    }
}

抽象类的注意事项

抽象类也可以定义普通的方法和变量

抽象类的优点

提高代码的复用性

什么时候用抽象类

当类与类之间是包含关系 比如说:狗是动物 我是人 面包是食物

final常量修饰符

可以修饰类、修饰方法、修饰变量

修饰类: 该类称为最终类 特点不能被继承

修饰方法: 该方法成为最终方法 特点不能被重写

修饰变量: 该变量只能被赋值一次

常量

常量: 定义一个常量
为了方便在其他类中被访问所以一般还会加上public修饰符

被static final两个修饰符修饰
常量命名规范:建议都采用大写字母命名,多个单词之前有_隔开

                            //常量名 
public static final String SCHOOL_NAME = "常量值";

final变量注意事项

如果变量是对象,只是对象地址只能赋值一次
final  int[] a={1,2,3,4};
//可以被修改
a[0]=100;
System.out.println(a[0]);

final使用场景

final一般应用于保存配置信息

final 优点

复用性高

类型转换错误

java.lang.ClassCastException

解决方案

转换类型前判断类型

平常使用 instanceof 关键词判断

instanceof

比较左边的对象引用是否属于右边的类

在多态情况下 想要调用具体子类的方法 可以使用instanceof判断

多态

多态实在继承实现情况下的一种现象 表现为多态 行为多态

多态写法: 父类引入指向子类对象(对象多态)

相同父类方法 具体子类不同 执行的内容不同(行为多态)

多态好处

提高代码复用性

解耦合

深耦合和浅耦合

深耦合: 类与类的关联关系太紧密

浅耦合: 类与类的关联关系比较小

权限修饰符

什么是权限修饰符?

权限修饰符是用来限制类的成员(成员变量 成员方法 构造器...)能够被访问的范围

每一种权限修饰符能够被访问的范围如下

修饰符在本类中在同一个包下的其他类任意包下的子类任意包下的任意类里
私有方法private
缺省缺省
受保护的protected
公开的public
private < 缺省 < protected < public

super

访问父类成员

super.成员变量 //访问父类成员变量

super.成员方法 //调用父类成员方法

super() //调用父类的无参构造器

super(参数)//调用父类的有参构造器

this

访问本类成员

this.成员变量 //访问本类成员变量

this.成员方法 //访问本类的成员方法

this() //调用本类的空参构造器

this(参数) //调用本类的有参构造器

super与this注意事项

注意:this和super访问构造方法 只能用到构造器的第一句话否则会报错

包含父类属性的有参构造器

当子类继承父类且父类存在非私有属性, 子类的构造方法可以接收父类的属性

super的使用场景

当子类被创建出来时,想同时调用父类构造器时用super();

继承extends

子类可以继承父类的非私有成员(成员变量和成员方法)

继承后对象的创建是由子类和父类共同实现的

继承好处

提高代码复用性

继承的注意事项

Java 只支持单继承,无法多继承

但是可以多层继承

java的祖宗类Object 如果不显示的继承object java是默认继承的

JAVA String Api

//String 类在 java.lang 包下,所以使用的时候不需要导包
//equals方法
//判断是否相同 参数Object 可以代表所有的引入数据类型
//引入数据类型的对比

//trim方法
//删除首尾空格

//contains 方法
//判断一个字符串是否包含某个字符串
//返回 Boolean

//startsWith 方法
//判断是否是指定字符串开头
//返回 Boolean

//emdWith 方法
//判断是否是指定字符串结尾
//返回 Boolean

//toUpperCase 方法
//将字符串的英文全部转换成大写

//toLowerCase 方法
//将字符串的英文全部转换成小写


//charAt 方法
//获取索引位置的字符
//返回字符

//length 方法
//获取字符串的长度
//返回int

//toCharArray 方法
//将字符串转换成字符数组
//返回 char[]

//substring 方法
//截取字符串
//int index 的时候
//从index索引位置截取到末尾(包含开始)
//start end
//从start-end索引位置内容(包含开始,不包含结束)

//replace 方法
//替换指定字符串

// split 方法
// 分隔字符串
//获取当前时间戳
// System.currentTimeMillis()
//主要用来拼接字符串

面向对象

package com.tonghui.day07;
public class Student {

    // 属性:用成员变量表示
    /**
     * 学生姓名
     */
    String name;
    /**
     * 年龄
     */
    int age;
    /**
     * 体重
     */
    double weight;
    /**
     * 性别
     */
    String sex;

    //行为:用成员方法表示(没有static关键的方法)

    /**
     * 行为: 学习方法
     */
    public void study(){
        System.out.println("好好学习");
    }
    /**
     * 行为: 打游戏
     * @param gameName 游戏名称
     */
    public void playGame(String gameName){
        System.out.println("喜欢打"+gameName);
    }
}
//不用
Student su = new Student();
su.name="张三";
//使用get和set对成员属性进行赋值和获取
/**
* 获取name值
*/
public String getName(){
    return name;
}
/**
* 设置name值
*/
public void getName(String name){
    this.name=name
}
//所有的成员变量都要加上private关键词
//作用:属性私有化,其他类访问不到成员变量,只能被本类访问
//public
//作用:成员行为公开,所有类都可以访问到
//Refrigerator.java
package com.tonghui.day07;

/**
 * @author TongHui
 * @date 2023.04.06 10:43
 */
public class Refrigerator{
    /**
     * 放进的物品
     */
    private String name;

    /**
     * 打开冰箱门
     */
    public void openDoor(){
        System.out.println("打开门");
    }
    /**
     * 把物品 放进冰箱
     */
    public void push(){
        System.out.println("把"+name+"放进冰箱");
    }
    /**
     * 关门
     */
    public void closeDoor(){
        System.out.println("关上冰箱门");
    }
    /**
     * 设置name
     * @param name 需要放进冰箱的物品
     */
    public void setName(String name) {
        this.name = name;
    }
}
//Test.java
package com.tonghui.day07;

/**
 * @author TongHui
 * @date 2023.04.06 10:41
 */
public class Test {
    public static void main(String[] args) {
        Refrigerator refrigerator = new Refrigerator();
        refrigerator.setName("大象");
        refrigerator.openDoor();
        refrigerator.push();
        refrigerator.closeDoor();
    }
}
//使用构造方法
//特点:
//类型和方法名相同
//没有返回值类型,连void都不能写

//调用格式
//new 类名(参数)

//每一个类都默认的一个无参构造器
//一旦写了有参的构造器 那么无参构造器就没了

//构造器与set方法给属性赋值的区别: 
//构造器只能给属性赋值一次(只适合于参数不多的情况)
//set方法可以多次

:::tips
一个类就是一个数据类型
:::

//1.定义位置
//成员变量:定义在类中方法外 作用于整个类
//局部变量:定义在方法内或方法生命上作用与方法里
//2.在内存中的位置
//成员变量在:堆内存中
//局部变量在:栈内存中
//3.生命周期
//成员变量:随着对象的创建而创建,随着对象的消失而消失
//局部变量:随着方法的调用而创建,随着方法的消失而消失
//4.初始化值
//成员变量有默认值
//局部变量没有默认值,必须赋值
//封装:
//就是将不想对外暴露的属性隐藏起来,对外提供一些方法供别人去操作,这样可以更安全,也可以提高代码的复用性
//this:
//可以用来区分局部变量和成员变量同名问题;
// this代表当前对象的引用 谁来调用这个方法 this就代表谁
//一个出租车 属性: 车牌 车型 所属公司
//行为: 载客 输出(尊敬的....乘客,....的车载您到了目的)
package com.tonghui.day07;

/**
 * 出租车的类
 * @author TongHui
 * @date 2023.04.06 16:18
 */
public class Taxi {
    /**
     * 车牌
     */
    private String id;
    /**
     * 所属公司
     */
    private String firm;
    /**
     * 车型
     */
    private String type;

    public Taxi() {
    }

    public Taxi(String id, String firm, String type) {
        this.id = id;
        this.firm = firm;
        this.type = type;
    }
    public void passenger(String name){
        System.out.println("尊敬的"+name+"乘客,"+firm+"的车载您到了目的");
    }
    /**
     * 获取
     * @return id
     */
    public String getId() {
        return id;
    }

    /**
     * 设置
     * @param id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * 获取
     * @return firm
     */
    public String getFirm() {
        return firm;
    }

    /**
     * 设置
     * @param firm
     */
    public void setFirm(String firm) {
        this.firm = firm;
    }

    /**
     * 获取
     * @return type
     */
    public String getType() {
        return type;
    }

    /**
     * 设置
     * @param type
     */
    public void setType(String type) {
        this.type = type;
    }
    @Override
    public String toString() {
        return "Taxicab{id = " + id + ", firm = " + firm + ", type = " + type + "}";
    }
}


Taxi taxi = new Taxi();
taxi.setId("浙A XXXXXXX");
taxi.setFirm("123");
taxi.setType("轿车");
taxi.passenger("TongHui");

Taxi taxi1=new Taxi("浙A XXXXXXX","1234","面包车");
taxi1.passenger("TongHui1");