栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaSE进阶

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaSE进阶

1、final关键字

final是Java语言中的一个关键字,表示最终的,不可变得。final可以修饰变量以及方法还有类等。

final修饰的类不能被继承,修饰的方法不能被重写与覆盖,修饰的变量只能赋值一次。

1.1 final修饰引用问题
package com.zh0u.final关键字;



public class FinalTest02 {
    public static void main(String[] args) {
        Person p1 = new Person(20);
        System.out.println(p1.age); // 20
        p1.age = 100;
        System.out.println(p1.age); // 100

        final Person person = new Person(30);
        person.age = 70;
        System.out.println(person.age);  // 70
    }
}

class Person{
    int age;

    public Person(){}

    public Person(int age){
        this.age = age;
    }
}

1.2 final修饰引用问题

==实例变量如果没有手动赋值,系统会赋默认值。final修饰的实例变量,系统不会赋默认值,要求程序员必须手动赋值。==这个手动赋值,在变量后面直接赋值可以,在构造方法中赋值也可以。

实例变量在对象被new的时候才会赋初始值。

package com.zh0u.final关键字;

public class FinalTest03 {
}

class User{
    // 实例变量
    // 编译器报错
    // final int age;

    // 实例变量
    final double height = 1.8;

    // 以下这堆代码全部联合起来,weight变量也只是赋值了1次。
    // 实例变量
    final double weight = 0;
    // 构造方法
    public User(){
        // 如果这里不写这行代码,系统会默认执行this.weight = 0;这样会报错。
        // 只要赶在系统赋默认值之前赋值就可以。
        // this.weight = 80;
    }
}

1.3 常量

final修饰的实例变量一般添加static修饰,final加static联合修饰的变量成为常量,一般常量变量名全部采用大写,中间使用下划线连接。

常量:实际上常量和静态变量一样,区别在于:“常量的值不能变”,都是存储在方法区,并且都是在类加载是初始化。

常量一般都是公开的。

package com.zh0u.final关键字;

public class FinalTest04 {
    public static void main(String[] args) {
        System.out.println(Chinese.COUNTRY);

        // 常量是无法重新赋值的。
        // Chinese.COUNTRY = "美国";
    }
}

class Chinese{
    // 身份证号,每个人都不一样,对象级别的。
    String idCard;
    // 姓名,对象不同姓名就不同。
    String name;
    // 国家的值是一个固定值:“中国”
    // 实例变量在堆中,一个对象一份。100个对象100份。
    // 实例变量既然使用final修饰了,说明该实例变量值不会随着对象的变化而变化。
    // 该实例变量前面应该添加:static关键字,变为静态的,存储在方法区。
    // final String country = "中国";
    final static String COUNTRY = "中国";
}

1.5 总结
  1. final修饰的类无法继承。
  2. final修饰的方法无法覆盖。
  3. final修饰的变量只能赋值一次。
  4. final修饰的引用一旦指向某个对象,则不能在重新指向其它对象,但该引用指向的对象内部的数据是可以修改的。
  5. final修饰的实例变量必须手动初始化,不能采用系统默认值。
  6. final修饰的实例变量一般和static联合使用,成为常量。
2、抽象类

类到对象是实例化,对象到类是抽象。

2.1 什么是抽象类

类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类,类本身是不存在的,所有抽象类无法创建对象《无法实例化》,所以抽象类是用来被子类继承的,抽象类的子类还可以为抽象类。

抽象类虽然无法实例化,但是抽象类有构造方法,这个构造方法是供子类使用的(子类在继承的时候会默认调用super()方法来调用父类的构造方法),抽象类的子类既可以是非抽象类也可以是抽象类。

final不能与关键字abstract一起修饰一个类。

抽象类也属于引用数据类型,定义的语法如下:

[修饰符列表] abstract class 类名{

	类体;

}
2.2 抽象方法

抽象类关联到一个概念:抽象方法,什么是抽象方法?抽象方法表示没有实现(没有方法体)的方法,如:

public abstract void doSome();

抽象方法的特点:

  1. 没有方法体也没有花括号,以分号结尾。
  2. 前面修饰符类表中有abstract关键字。

抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中。

package com.zh0u.抽象类;

public class AbstractTest01 {
    public static void main(String[] args) {
        // 抽象类不能被继承
        // new Account();

        // 思考:以下程序能不能使用多态?答案:能
        // 以下的代码就是面向抽象编程思想。
        Account account = new CreditAccount();  // 向上转型,父引用指向子类对象。
        account.doSome(); // 信用卡取款中......
    }
}

abstract class Account{
    public Account(){}  // 这个构造方法由系统系统自动提供,用来供子类使用。
    Account(String name){}

    public abstract void doSome();  // 抽象类中定义了抽象方法,则子类必须对这个抽象方法进行继承。
}


// 非抽象类继承抽象类,必须将父类中的继承过来的抽象类进行重写或实现。
// 原因是子类从父类(抽象类)中继承过来抽象方法只能出现在抽象类中,但是子类不是,所以只能重写。
class CreditAccount extends Account{
    public CreditAccount(){
        super();
    }

    // 子类重写父类(抽象类)中的方法
    public void doSome(){
        System.out.println("信用卡取款中......");
    }
}

// 当然如果子类也是抽象类,那么也可以不去重写父类中的抽象方法。原因是子类继承过来的抽象方法doSome()也是在抽象方法AgriculturalAccount类中。
abstract class AgriculturalAccount extends Account{

}

面试题(判断题):Java语言汇总凡是没有方法体的方法都是抽象方法?

不对,错误的。

Object类中就有很多方法都没有方法体,都是以“;”号结尾,但它们度不是抽象方法,如:

public native int hashCode();

这个方法底层调用了C++写的动态链接库程序,前面的修饰符列表中没有“abstract”,有一个native,表示调用JVM本地程序。

3、接口

接口也是一种引用数据类型,编译之后也会生成一个class字节码文件。接口是完全抽象的或也可以说接口是特殊的抽象类。

3.1 接口的基础语法

接口的定义:

[修饰符列表] interface 接口名{}

接口支持继承和多继承,即一个接口可以继承多个接口,多个接口之间使用“,”分隔开即可。

interface A{}

interface B{}

interface C extends A, B{
    
}

接口中只包含两部分内容,一部分是:常量(值不能改变),另一部分是:抽象方法。

接口中所有的元素都是public修饰的。

接口中的抽象方法定义时:public abstract 修饰符可以省略,编译器编译的时候会自动加上。

接口中的方法都是抽象方法,所有接口中的方法不能有方法体。

类通过implements关键字来对接口的方法进行实现(继承),通过implements实现(继承)的类,必须重写对应接口中的所有抽象方法。

总结

  1. 接口是一种“引用数据类型”。
  2. 接口是完全抽象的。
  3. 接口怎么定义:[修饰符列表] interface 接口名{}
  4. 接口支持多继承
  5. 接口中只有常量+抽象方法
  6. 接口中所有的元素都是public修饰的
  7. 接口中抽象方法的public abstract可以省略。
  8. 接口中常量的public static final可以省略。
  9. 接口中方法不能有方法体。
  10. 一个非抽象的类,实现接口的时候,必须将接口中所有的方法加以实现。
  11. 一个类可以实现多个接口。
  12. extends和implements可以共存,extends在前,implements在后。
  13. 使用接口,写代码的时候,可以使用多态(父类型引用指向子类型对象)。
3.2 面向接口编程

类和类之间叫做继承,类和接口之间叫做“实现”,这里的实现也可以理解为“继承”。

package com.zh0u.接口;

public class InterfaceTest02 {
    public static void main(String[] args) {
        // 访问接口常量
        System.out.println(MyMath.PI);  // 3.1415936

        // 注意接口是无法实例化的,以下代码编译器在编译是会报错
        // new MyMath();

        // 核心思想: 面向接口编程(核心还是多态)
        MyMath myMath = new MyMathImpl();
        System.out.println(myMath.sub(20, 10));
        System.out.println(myMath.sum(20, 10));
    }
}

interface MyMath{
    // 常量 public static final 可以省略
    public static final double PI = 3.1415936;

    // 抽象方法,public abstract 可以省略
    public abstract int sum(int a, int b);

    // 接口中的方法不能有方法体,以下代码会编译器会报错。
    // void doSome(){}

    // 相减的抽象方法
    int sub(int a, int b);
}

class MyMathImpl implements MyMath{  // 类通过implements来实现接口中的方法

    @Override
    public int sum(int a, int b) {  // 这里的public不能省略
        return a + b;
    }

    @Override
    public int sub(int a, int b) {
        return a - b;
    }
}

接口和接口之间支持多继承,那么一个类可以同时实现多个接口吗?答案:可以。

interface W{
    public abstract int m1();
}

interface Y{
    public abstract int m2();
}

interface Z{
    public abstract int m3();
}

class t implements W, Y, Z{

    @Override
    public int m1() {
        return 0;
    }

    @Override
    public int m2() {
        return 0;
    }

    @Override
    public int m3() {
        return 0;
    }
}
3.3 继承和实现连用

extends和implements可以共存,extends在前,implements在后。

public class InterfaceTest04 {
    public static void main(String[] args) {
        // 面向接口编程 ---多态----
        Flyable cat = new Cat();
        cat.fly();  // 飞猫起飞,翱翔太空的一只猫!!!

        Flyable pig = new Pig();
        pig.fly();  // 我是一直会飞的飞猪!!!
    }
}

// 动物类:父类
class Animal{}

// 可飞翔的接口(是一对翅膀)
// 能插拔的就是接口。(没有接口就不能插拔)。
// 接口通常提取的是行为动作。
interface Flyable{
    void fly();
}

// 动物类子类:猫类
// Flyable是一个接口,是一对翅膀的接口,通过接口查到猫身上,让猫变得可以飞翔。
class Cat extends Animal implements Flyable{
    public void fly(){
        System.out.println("飞猫起飞,翱翔太空的一只猫!!!");
    }
}

// 蛇类:如果不想让它飞,可以不实现Flyable接口。
// 没有实现这个接口表示你没有翅膀,没有给你插翅膀,你肯定不能飞。
class Snake extends Animal{

}

// 猪想让做一只飞猪,我们给它插上翅膀即可。
class Pig extends Animal implements Flyable{
    public void fly(){
        System.out.println("我是一直会飞的飞猪!!!");
    }
}

// 这里没有写 extends关键字,但是Fish默认还是要继承Object类
class Fish implements Flyable{
    @Override
    public void fly() {
        System.out.println("我是六眼飞鱼(流言蜚语)!!!");
    }
}
3.4 接口在开发中的作用

接口在开发中的作用,类似于多态在开发中的作用。

**多态:**面向抽象编程,不行面向具体编程。降低程序的耦合度,提供程序的扩展力(OCP)原则。

接口的作用?

接口是完全抽象的,而我们以后正好要求面向抽象编程。面向抽象编程这句话可以修改为:“面向接口编程”。接口的扩展性好,可插拔,符合OCP开发原则。

接口的使用离不开多态机制(接口+多态才可以达到降低耦合度)。

以后进行大项目开发,一般都是讲项目分离成一个模块一个模块的,各模块之间采用接口衔接。降低耦合度。

FoodMenu.java

package com.zh0u.接口在开发中的作用;



public interface FoodMenu {
    // 西红柿炒蛋
    void shiZiChaoJiDan();

    // 鱼香肉丝
    void yuXiangRouSi();
}

ChineseCooker.java

package com.zh0u.接口在开发中的作用;

public class ChineseCooker implements FoodMenu{
    @Override
    public void shiZiChaoJiDan() {
        System.out.println("中国厨师做的西红柿炒蛋!!!");
    }

    @Override
    public void yuXiangRouSi() {
        System.out.println("中国厨师做的鱼香肉丝!!!");
    }
}

WesternCooker.java

package com.zh0u.接口在开发中的作用;

public class WesternCooker implements FoodMenu{
    @Override
    public void shiZiChaoJiDan() {
        System.out.println("西方厨师做的西红柿炒蛋!!!");
    }

    @Override
    public void yuXiangRouSi() {
        System.out.println("西方厨师做的鱼香肉丝!!!");
    }
}

Customer.java

package com.zh0u.接口在开发中的作用;

// 顾客
public class Customer {
    // 顾客手里有一个菜单
    // Customer has a FoodMenu! 重点:has a
    // 重点:以后凡是能够使用 has a 来描述的,统一以属性的方式存在。
    // 实例变量,属性
    private FoodMenu foodMenu; // 面向接口编程(抽象编程)可以降低程序的耦合度,提高程序的扩展力。

    // 如果以下这样写,就表示写死了(焊接了,没有课插拔了)
    // 中餐厨师
    // ChineseCooker chineseCooker;
    // 西餐厨师
    // WesternCooker westernCooker;

    // 构造方法
    public Customer(){}
    public Customer(FoodMenu foodMenu){this.foodMenu = foodMenu;}

    // setter and getter
    public FoodMenu getFoodMenu() {
        return foodMenu;
    }

    public void setFoodMenu(FoodMenu foodMenu) {
        this.foodMenu = foodMenu;
    }

    // 顾客点菜的方法
    public void order(){
        this.foodMenu.yuXiangRouSi();
        this.foodMenu.shiZiChaoJiDan();
    }
}


Test.java

package com.zh0u.接口在开发中的作用;public class Test {    public static void main(String[] args) {        // 创建厨师对象        FoodMenu chineseCooker = new ChineseCooker();        // 创建顾客对象        Customer customer = new Customer(chineseCooker);        // 顾客点菜        customer.order();    }}
3.5 类型之间的关系(理解)

is a、has a、like a

is a:

​ Cat is a Animal(猫是一个动物),凡是能够满足is a的表示“继承关系”。

has a:

​ I has a Pen(我有一只笔),凡是能够满足has a关系的表示“关联关系”,关联关系通常以“属性”的形式存在。

like a:

​ Cooker like a FoodMenu(厨师像一个菜单一样),凡是能够满足like a关系的表示“实现关系”,实现关系通常是:类实现接口。

4、抽象类与接口的区别

这里只说一下抽象类和接口在语法上的区别,至于以后抽象类和几口应该怎么进行选择,通过项目区学习。

  1. 抽象类是半抽象的,接口是完全抽象的。
  2. 抽象类中有构造方法,接口中没有构造方法。
  3. 接口和接口之间支持多继承,类和类之间只能单继承。
  4. 一个类可以同时实现多个接口,一个抽象类只能继承一个类。
  5. 接口中只允许出现常量和抽象方法。
  6. 一般抽象类使用的还是少,接口一般都是对“行为”的抽象。
5、Object类

JDK类库的根类 — Object

先研究一下Object,因为这些方法都是所有子类通用的,任何一个类默认继承Object。就算没有直接继承,最终也会间接继承。

Object类当中的那些常用方法,我们可以到哪里去找?

第一种:去源代码中(不推荐,难度较大)。

第二种:去查阅java类库的帮助文档。

目前为止我们只需要知道这几个方法即可:

protected Object clone()   对象克隆

boolean equals(Object obj)   判断两个对象是否相等

int hashCode()   获取对象哈希值的一个方法

protected void finalize()    垃圾回收器负责调用的方法

String toString()   将对象转换为字符串形式
5.1 toString方法

源代码

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

源代码上toString()方法的默认实现是:类名@对象的内存地址转换为十六进制的形式。

toString的作用是通过调用这个方法可以将一个“Java对象”转换成“字符串”的形式输出。

SUN公司开发Java语言的时候,建议所有的子类都去重写toString()方法,toString()方法应该是一个简洁的、详实的、容易阅读的。

注意:Java在输出引用的时候,如果不调用toString()方法,也会默认调用它。

package com.zh0u.Object类;

public class Object_toString {
    public static void main(String[] args) {
        System.out.println(new definedDate(1970, 1, 1));  // 直接输出引用,默认也会调用 toString() 方法
    }
}

class definedDate{
    int year, month, day;
    public definedDate(){}
    public definedDate(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

    @Override
    public String toString() {  // 重新父类中的 toString() 方法
        return "definedDate{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}
5.2 equals方法

源代码:

public boolean equals(Object obj) {
        return (this == obj);
    }

这个方法是Object类默认实现的,判断两个java对象是否相等,不能使用“ == ” ,因为“==

补充:什么是API?

应用程序编程接口,整个JDK的类库就是一个javase的API,每个API都会配置一套API帮助文档。

6、package和import 6.1 关于Java语言的package和import机制:
  1. 为什么使用package?

package是java中包机制。包机制的作用是为了方便程序的管理。不同功能的类分别存在在不同的包下(按照功能划分,不同软件包具有不同的功能)。

  1. package的怎么用?

package是一个关键字,后面加包名,例如:package com.zh0u.javase.interfacetest;

注意:package语句只允许出现在java源代码的第一行。

  1. 包名命名规范?

一般都采用公司域名倒序的方式(因为公司域名具有唯一性)。命名规范为:

公司域名倒序 + 项目名 + 模块名… [ + 功能名 ]

  1. 对于带有package的java程序怎么编译?怎么运行?

采用之前的编译方式和运行不行了,类名不再是:HelloWorld了,类名是:com.zh0u.javase.import_test.HelloWorld

编译:javac -d . HelloWorld.java。-d 带包编译,.代表编译之后生成的东西放到当前目录下(点代表当前目录)。

运行:java com.zh0u.javase.import_test.HelloWorld

package com.zh0u.interface_test;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello world!");
    }
}
6.2 import
  1. import什么时候使用?

在A类中使用B类,如果A类和B类在同一个包下,不需要import,否则就需要使用import。

  1. import的用法。

import语句只能出现在package语句之下,class声明之上。

import语句还可以使用*的方式导入类。

import com.zh0u.接口.*;

java.lang包下面的直接类不需要使用import导入,直接可以使用。如:String.java。

7、访问权限控制

Java访问级别修饰符主要包括:private、protected 和 public ,可以限定其他类对该类、属性和方法的使用权限。

修饰符类的内部同一个包里子类任何地方
privateYNNN
defaultYYNN
protectedYYYN
publicYYYY

注意以上对类和接口的修饰只有 publicdefault ,内部类除外。

范围从大到小排序:public > protected > default > private

package com.zh0u.访问控制权限;

public class User {
    // 给一些属性
    // 私有
    private int id;
    // 受保护
    protected int age;
    // 公开
    public int weight;
    // 默认
    String name;

    // 方法
    public void m1(){}
    private void m2(){}
    void m3(){}
    protected void m4(){}

    // 静态方法也可以使用四种访问权限修饰符
}

// java: 此处不允许使用修饰符private


// java: 此处不允许使用修饰符protected


// default
class J{}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/337573.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号