JAVA - 学习记录第八天

目录

一、抽象类和接口(掌握)

(一)抽象方法和抽象类

(二)接口 interface

二、字符串 String 类(掌握)

(一)String 基础

(二)String 类和常量

(三)String 类常用的方法

(四)字符串相等的判断

三、内部类(了解)

(一)概念 

(二)非静态内部类 

(三)静态内部类:

 (四)匿名内部类

(五)局部内部类 


一、抽象类和接口(掌握)

(一)抽象方法和抽象类

  • 抽象方法:使用 abstract 修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
  • 抽象类:包含抽象方法的类就是抽象类。通过 abstract 方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。

 测试:

//创建抽象类
abstract class Animal {
    abstract public void birdFly1(); //抽象方法
}
class Bird  extends Animal {
    //子类必须实现父类的抽象方法,否则编译错误
    public void birdFly1() {
        System.out.println("我会飞");
    }//添加一个方法
    public void birdFly2(){
        System.out.println("飞得高");
    }
}
//测试抽象类
public class TestAbstractClass {
    public static void main(String[] args) {
        Bird a = new Bird();
        a.birdFly1();
        a.birdFly2();
    }
}

抽象类的使用要点:

  1. 有抽象方法的类只能定义成抽象类
  2. 抽象类不能实例化,即不能用 new 来实例化抽象类。
  3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来 new 实例, 只能用来被子类调用。
  4. 抽象类只能用来被继承。
  5. 抽象方法必须被子类实现。

(二)接口 interface

①接口的作用

        接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。

区别:

  • 普通类:具体实现
  • 抽象类:具体实现,规范(抽象方法)
  • 接口:规范!

②如何定义和使用接口(JDK8 以前)

声明格式:

        [访问修饰符]         interface 接口名         [extends        父接口 1,父接口 2…]  {

                常量定义;

                方法定义;

        }

定义接口的详细说明:

  1. 访问修饰符:只能是 public 或默认。
  2. 接口名:和类名采用相同命名机制。
  3. extends:接口可以多继承。
  4. 常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。
  5. 方法:接口中的方法只能是:public abstract。 省略的话,也是 public abs 。

要点:

  1. 子类通过 implements 来实现接口中的规范。
  2. 接口不能创建实例,但是可用于声明引用变量类型。
  3. 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是 public 的。
  4. JDK1.8(不含 8)之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造 方法、普通方法。
  5. JDK1.8(含 8)后,接口中包含普通的静态方法、默认方法。

测试:

public class TestInterface {
    public static void main(String[] args) {
        Student student = new GoodStudent();
        student.way();
        System.out.println(Best.Grade);
        
        Best best = new GoodWorker();
        best.diligent();

    }
}
/**学生接口*/
interface Student {
    void way(); //总是:public abstract void fly();
}
/**优秀接口*/
interface Best {
    String Grade = "90+"; // 总是:public static final 类型的;
    void diligent();
}
/**好学生 类实现好学生接口和优秀接口*/
class GoodStudent implements Student, Best{
    public void way() {
        System.out.println("好好学习天天向上!");
    }
    public void diligent() {
        System.out.println("多读书多看报!");
    }
}
class GoodWorker implements Best {
    public void diligent() {
        System.out.println("做事勤劳!");
    }
}

测试结果:

 ③接口中定义静态方法和默认方法(JDK8 以后)

  • JAVA8 之前,接口里的方法要求全部是抽象方法。
  • JAVA8(含 8)之后,以后允许在接口里定义默认方法和类方法。

Ⅰ. 默认方法 

        Java 8 及以上新版本,允许给接口添加一个非抽象的方法实现,只需要使用 default 关键字即可,这个特征又叫做默认方法(也称为扩展方法)。 默认方法和抽象方法的区别是抽象方法必须要被实现,默认方法不是。作为替代方式,接口可以提供默认方法的实现,所有这个接口的实现类都会通过继承得到这个方法。

测试:

public class Testdefault {
    public static void main(String[] args) {
        A a = new Test_A();
        a.moren();
    }
}

interface A{

    default void moren(){
        System.out.println("接口A中的默认方法");
    }
}

class Test_A implements A{//子类通过 implements 来实现接口中的规范
    //重写方法moren
    @Override
    public void moren() {
        System.out.println("Test_A.moren");
    }
}

Ⅱ. 静态方法

        JAVA8 以后,也可以在接口中直接定义静态方法的实现。这个静态方法直接从属于接口(接口也是类,一种特殊的类),可以通过接口名调用。 如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直接从属于子类。 可以通过子类名直接调用。

Ⅲ. 静态方法和默认方法

④接口可以多继承

        接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。

⑤面向接口编程(了解)

        接口就是规范,就是项目中最稳定的核心! 面向接口编程可以让我们把握住真正核心的东西,使实现复杂多变的需求成为可能。

二、字符串 String 类(掌握)

(一)String 基础

  • String 类又称作不可变字符序列。
  • String 位于 java.lang 包中,Java 程序默认导入 java.lang 包下的所有类。
  • Java 字符串就是 Unicode 字符序列,例如字符串“Java”就是 4 个 Unicode 字 符’J’、’a’、’v’、’a’组成的。
  • Java 没有内置的字符串类型,而是在标准 Java 类库中提供了一个预定义的类 String,每个用双引号括起来的字符串都是 String 类的一个实例

(二)String 类和常量

常量池也分了以下三种:

  1. 全局字符串常量池(String Pool),其存放的内容是在类加载完成后存到 String Pool 中的,在每个 VM 中只有一份,存放的是字符串常量的引用值(在堆中生成字符串对象实例)。
  2. class 文件常量池(Class Constant Pool),其是在编译的时候每个 class 都有的,在编译阶段,存放的是常量(文本字 符串、final 常量等)和符号引用。
  3. 运行时常量池(Runtime Constant Pool),其是在类加载完成之后,将每个 class 常量池中的符号引用值转存到运行时 常量池中,也就是说,每个 class 都有一个运行时常量池,类在解析之后,将符号引用替换 成直接引用,与全局常量池中的引用值保持一致。

字符串相等判断(以后一般判断字符串值是否相等, 使用 equals()),测试:

public class Test {
    public static void main(String[] args) {
    String s1 = "abc";
    String s2 = new String("abc");
    String s3 = "abc";

        System.out.println(s1 == s3);
        System.out.println(s2 == s3);
        System.out.println(s2.equals(s3));
    }
}

(三)String 类常用的方法

方法解释说明
char charAt(int index)返回字符串中第 index 个字符
boolean equals(String other)如果字符串与 other 相等,返回 true;否则,返回false
boolean equalsIgnoreCase (String other)如果字符串与 other 相等(忽略大小写),则返回 true;否则, 返回 false
int indexOf(String str)返回从头开始查找第一个子字符串 str 在字符串中的索引位 置。如果未找到子字符串 str,则返回-1
astIndexOf()返回从末尾开始查找第一个子字符串 str 在字符串中的索引位 置。如果未找到子字符串 str,则返回-1
int length()返回字符串的长度
tring replace(char oldChar, char newChar)返回一个新串,它是通过用 newChar 替换此字符串中出现的 所有 oldChar 而生成的
boolean startsWith(String prefix)如果字符串以 prefix开始,则返回ture
boolean  endsWith(String prefix)如果字符串以 prefix结尾,则返回ture
String substring(int beginIndex)返回一个新字符串,该串包含从原始字符串 beginIndex 到串尾
tring substring(int beginIndex, int endsIndex)返回一个新字符串,该串包含从原始字符串 beginIndex 到串 尾或 endIndex-1 的所有字符
String toLowerCase()返回一个新字符串,该串将原始字符串中的所有大写字母改成小写字母
String toUpperCase()返回一个新字符串,该串将原始字符串中的所有小写字母改成 大写字母
String trim()返回一个新字符串,该串删除了原始字符串头部和尾部的空 格

测试:

public class TestString {
    public static void main(String[] args){
        String a1 = "    Java Dean Java!    ";
        String a2 = "    java dean Java!    ";
        System.out.println(a1.charAt(15));//提取下标为 15 的字符
        System.out.println(a1.equals(a2));//比较两个字符串是否相等
        System.out.println(a1.equalsIgnoreCase(a2));//比较两个字符串(忽略大小写)
        System.out.println(a1.indexOf("Java"));//从头开始索引str的位置,无则-1
        System.out.println(a1.lastIndexOf("Java"));//从尾开始查找str的索引位置
        System.out.println(a1.length());//字符串的长度
        System.out.println(a1.replace(" ","&"));;//将 a1 中的空格替换成&
        String a3 = "Hello World?HELLO WORLD";
        String a4 = "";
        System.out.println(a3.startsWith("Hello"));//是否以 Hello 开头
        System.out.println(a3.endsWith("D"));//是否以 D 结尾
        a4 = a3.substring(4);//提取子字符串:从下标为 4 的开始到字符串结尾为止
        System.out.println(a4);
        a4 = a3.substring(4,7);//提取子字符串:下标[4, 7) 不包括 7
        System.out.println(a4);
        a4 = a3.toLowerCase();//转小写
        System.out.println(a4);
        a4 = a3.toUpperCase();//转大写
        System.out.println(a4);
        a4 = a1.trim();//去除字符串首尾的空格。注意:中间的空格不能去除
        System.out.println(a4);
        System.out.println(a1);//因为 String 是不可变字符串,所以 a1 不变
    }
}

测试效果图:

(四)字符串相等的判断

  1. equals 方法用来检测两个字符串内容是否相等。如果字符串 s 和 t 内容相等,则 s.equals(t)返回 true,否则返回 false。
  2. 要测试两个字符串除了大小写区别外是否是相等的,需要使用 equalsIgnoreCase 方法。
  3. 判断字符串是否相等不要使用"=="。

三、内部类(了解)

        内部类是一类特殊的类,指的是定义在一个类的内部的类。实际开发中,为了方便的使 用外部类的相关属性和方法,这时候我们通常会定义一个内部类。

(一)概念 

一般情况,我们把类定义成独立的单元。有些情况下,我们把一个类放在另一个类的内 部定义,称为内部类(innerclasses)。内部类可以使用 public、default、protected 、private 以及 static 修饰。而外部顶 级类(我们以前接触的类)只能使用 public 和 default 修饰。

注意

内部类只是一个编译时概念,一旦我们编译成功,就会成为完全不同的两个类。对于一个名为 Outer 的外部类和其内部定义的名为 Inner 的内部类。编译完成后会出现 Outer.class 和 Outer$Inner.class 两个类的字节码文件。所以内部类是相对独立的一种存在,其成员变量/方法名可以和外部类的相同。

内部类的作用:

  • 内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直 接访问。
  • 内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。 但外部类 不能访问内部类的内部属性。

(二)成员内部类 

①非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)

  • 非静态内部类对象必须寄存在一个外部类对象里。因此,如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象。
  • 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员。
  • 非静态内部类不能有静态方法、静态属性和静态初始化块。
  • 成员变量访问要点: 1. 内部类里方法的局部变量:变量名。 2. 内部类属性:this.变量名。 3. 外部类属性:外部类名.this.变量名。

内部类的访问:

  1. 外部类中定义内部类:new Inner()。
  2. 外部类以外的地方使用非静态内部类: Outer.Inner varname = new Outer().new Inner()。 

/**

 * 测试非静态内部类

 */

public class TestInnerClass1 {

        public static void main(String[ ] args) {

                //先创建外部类实例,然后使用该外部类实例创建内部类实例

                Outer1.Inner1 inner = new Outer1().new Inner1();

                 inner.show();

        }

②静态内部类:

定义方式:

static class ClassName {

        //类体

}

 使用要点:

  1. 静态内部类可以访问外部类的静态成员,不能访问外部类的普通成员。
  2. 静态内部类看做外部类的一个静态成员。

(三)匿名内部类

        适合那种只需要使用一次的类。比如:键盘监听操作等等。在安卓开发、awt、swing 开发中常见。
定义方式:

new        父类构造器(实参类表) \实现接口 () {

         //匿名内部类类体!

}

 注意

  • 匿名内部类没有访问修饰符。
  • 匿名内部类没有构造方法。因为它连名字都没有那又何来构造方法呢。

(四)局部内部类 

定义在方法内部的,作用域只限于本方法,称为局部内部类。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值