• 第5章 Java 高级特性


    第5章 Java高级特性

    5.1 封装性

    封装是指将类中的某些信息隐藏在类的内部,不允许外部程序直接访问,只能通过 该类提供的方法实现对隐藏信息的访问或操作。
    e.g.
    class Student{
        private String name;
        private int age;
    
        // 带参数构造方法
        Student(String name,int age){
            this.name = name;
            this.age = age;
        }
    
        // 获取name的信息
        String getName(){
            return name;
        }
    
        // 设置age的值
        void setAge(int age){
            this.age = age;
        }
    
        // 获取age信息
        int getAge(){
            return age;
        }
    }
    
    public class Demo1 {
        public static void main(String[] args) {
            // 创建Student的实例(对象) s1
            Student s1 = new Student("张三",18);
            // 修改age字段的值
            s1.setAge(19);
            System.out.printf("姓名:%s,年龄:%d",s1.getName(),s1.getAge());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    5.2 继承

    继承是指子类可以拥有父类的全部属性和行为(方法),是类与类之间的一种关系。Java中类的继承只支持单继承,即一个子类只能继承一个父类。
    e.g.
    // 定义基类
    class People{
        private String name;
        private int age;
    
        // 父类的构造方法
        People(String name,int age){
            this.name = name;
            this.age = age;
        }
    
        void show(){
            System.out.printf("姓名:%s,年龄:%d\n",name,age);
        }
        // 获取name信息
        String getName(){
            return name;
        }
        // 修改字段age的值
        void setAge(int age){
            this.age = age;
        }
        // 获取age信息
        int getAge(){
            return age;
        }
    }
    
    // 定义子类
    class Student extends People{
        // 子类中构造方法
        Student(String name,int age){
            // 调用父类的构造器完成对象的初始化操作
            super(name,age);
        }
    
        // 重写父类中的show()方法,从而实现对父类方法的修改或覆盖
        @Override
        void show() {
            // 调用父类中的show()方法
            super.show();
            System.out.println("这是子类中的show()方法");
        }
    }
    
    public class Demo1 {
        public static void main(String[] args) {
            // 创建Student的实例(对象) s1
            Student s1 = new Student("李四",18);
            s1.setAge(19);
            s1.show();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    5.3 方法的重载和重写

    1、方法的重载(同一个类中)

    方法名相同,方法的参数列表不同。
    PS: 与方法的返回类型无关,返回类型可以相同也可以不同。
    e.g.
    public class Demo2 {
        // 返回两个数的最大值
        static double max(int x,float y){
            return x>y?x:y;
        }
    
        //返回三个数的最大值,与上面的方法构成重载
        static double max(int x,float y,double z){
            return x>y?(x>z?x:z):(y>z?y:z);
        }
    
        //返回三个数的最大值,与上面的方法构成重载
        static double max(float x,int y,double z){
            return x>y?(x>z?x:z):(y>z?y:z);
        }
    
        public static void main(String[] args) {
            System.out.println(max(2,.5f));
            System.out.println(max(23,.5f,3.14));
            System.out.println(max(2f,5,3.14));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2、方法的重写(在不同的类中)

    指在子类中重写父类中的方法,从而实现对父类方法的修改或覆盖;
    PS: 重写时,不能使用比父类方法更严格的访问权限修饰符。
    e.g.
    // 父类
    class Animal{
        void run(){
            System.out.println("动物在奔跑");
        }
    }
    
    // 子类
    class Cat extends Animal{
        // 重写父类中的run()方法,
        void run(){
            System.out.println("猫在抓老鼠");
        }
    }
    
    public class Demo3 {
        public static void main(String[] args) {
            Cat c1 = new Cat();
            c1.run();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5.4 对象的类型转换

    (1)向上转型

    父类的引用指向子类的对象;

    (2)向下转型

    子类的引用指向父类的对象;
    e.g.
    // 基类
    class Person{
        void run(){
            System.out.println("在跑步");
        }
    }
    
    // 子类
    class Student extends Person{
        @Override
        void run() {
            System.out.println("学生在跑步");
        }
    
        // 子类中定义的方法
        void study(){
            System.out.println("学生在学习");
        }
    }
    
    public class Demo1 {
        public static void main(String[] args) {
            // 向上转型:父类的引用指向子类的对象
            Person p1 = new Student();
            p1.run();
            // p1.study(); 不能调用子类中定义的成员
    
            // 向下转型:子类的引用指向父类的对象
            Student s1 = (Student) p1;
            s1.run();
            s1.study();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    关于对象类型转换的两点说明:
    (1)向上转型对象只能访问从基类继承的成员及重写的方法,子类中定义的成员不能被访问;
    (2)向上转型可以减少重复代码,提高系统的扩展性;

    5.5 多态性

    多态指同一种行为(方法)具有多种表现形态;

    (1)编译时多态(静态的)

    主要指方法的重载,编译时通过方法参数列表不同来进行区分;

    (2)运行时多态(动态的)

    同一类型的引用使用不同的实例而执行不同的操作,产生不同的结果; 实现方式:继承、接口
    class Animal{
        void run(){
            System.out.println("动物在奔跑");
        }
    }
    
    class Cat extends Animal{
        void run(){
            System.out.println("猫在抓老鼠");
        }
    }
    
    class Dog extends Animal{
        void run(){
            System.out.println("狗在奔跑");
        }
    }
    
    public class Demo2 {
    
        void show(Animal a){
            a.run();
        }
    
        public static void main(String[] args) {
            
            Animal a = new Animal();
            // 向上转型
            Animal a1 = new Cat();
            Animal a2 = new Dog();
    
            Demo2 d2 = new Demo2();
    
            // 多态的表现
            d2.show(a);
            d2.show(a1);
            d2.show(a2);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    5.6 可变长参数

    e.g.
    public class Demo3 {
        int f(int x,int y){
            System.out.println("+++++++++");
            return x+y;
        }
        int f(int x,int y,int z){
            return x+y+z;
        }
    //    // 与第1、2个方法构成重载
    //    int f(int[] x){
    //        int sum=0;
    //        for(int k:x){
    //            sum+=k; // sum=sum+k;
    //        }
    //        return sum;
    //    }
    
        // 与第1、2个方法构成重载;与第3个方法不构成重载,系统认为这两个方法等价
        int f(int ... x){
            int sum=0;
            for(int k:x){
                sum+=k; // sum=sum+k;
            }
            return sum;
        }
    
        public static void main(String[] args) {
            Demo3 d3 = new Demo3();
            System.out.println(d3.f(new int[]{25,30,40,50,60}));
            System.out.println(d3.f(20,30));
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    public class Demo4 {
        static void f(String ... str){
            String s1 = "";
            for(String s : str){
                s1 +=s;
            }
            System.out.println(s1);
        }
    
        public static void main(String[] args) {
            f("Hello"," ","Java","!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.7 抽象类

    使用abstract修饰的类称为抽象类;
    e.g.
    // 抽象类
    abstract class A{
        // 抽象方法
        abstract double area(int r);
    }
    
    class B extends A{
        // 实现抽象类中的抽象方法
        double area(int r){
            return Math.PI*r*r;
        }
    }
    
    public class Demo3 {
        public static void main(String[] args) {
            B b = new B();
            System.out.println(b.area(5));
            System.out.println(b.area(10));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    e.g.
    // 抽象类
    abstract class A{
        int r;
        int w,h;
        // 构造器
        A(int r){
            this.r = r;
        }
        A(int w,int h){
            this.w = w;
            this.h = h;
        }
        // 抽象方法
        abstract double area();
    }
    
    class B extends A{
        B(int r){
            super(r);
        }
        // 实现抽象类中的抽象方法
        double area(){
            return Math.PI*r*r;
        }
    }
    
    class C extends A{
        C(int w,int h){
            super(w,h);
        }
        // 实现抽象类中的抽象方法
        double area(){
            return w*h;
        }
    }
    
    public class Demo3 {
        public static void main(String[] args) {
            B b = new B(3);
            System.out.println(b.area());
            C c = new C(4,5);
            System.out.println(c.area());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    关于抽象类的几点说明:
    A、由于抽象类是需要继承的,所有不能使用final修饰;
    B、抽象类的子类也可是抽象类;
    C、抽象类不能使用new来实例化,但可以有构造器;
    D、抽象方法必须存在于抽象类中,且不能使用static、final修饰;
    E、子类实现抽象类时,必须实现抽象类中的所有抽象方法;

    5.8 接口

    抽象类是从多个类中抽象出来的模板,如果将这种抽象进行的更彻底,则可以提炼出一种更加特殊的“抽象类”即接口。
    接口中的成员包含:全局常量、公共抽象方法、静态方法。
    e.g.
    public interface Itf1 {
        // var: 默认是 public static final的
        double PI=3.1415926;
    
        // abstract method: 默认是 public abstract的
        double area(int r);
    
        // static method: 默认是 public 的
        static void f(){
            System.out.println("这是接口中的静态方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    // 实现接口 Itf1
    public class Demo7 implements Itf1{
        // 实现接口中的抽象方法
        public double area(int r) {
            return PI*r*r;
        }
        
        public static void main(String[] args) {
            // 创建类的实例(对象)
            Demo7 d7 = new Demo7();
            double s = d7.area(5);
            System.out.println("圆的面积为:"+s);
            // 调用接口中的静态方法
            Itf1.f();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    关于接口的几点说明:
    ①接口中的变量会隐式指定为public static final的,即全局常量;
    ②接口中的抽象方法会隐式指定为public abstract的;
    ③接口中不能定义代码块、构造器;
    ④接口中可以定义静态方法(默认是public的),但不能被继承;
    ⑤接口支持多继承;类只支持单继承;
    ⑥一个类可以实现多个接口。
    e.g.
    public interface Itf2{
        double E = 2.71828;
    }
    
    // 接口的多继承
    public interface Itf3 extends Itf1,Itf2{
    
    }
    
    // 一个类可以实现多个接口,实现接口 Itf1,Itf2,Itf3
    public class Demo7 implements Itf1,Itf2,Itf3 {
        // 实现接口中的抽象方法
        public double area(int r) {
            return PI*r*r;
        }
        
        public static void main(String[] args) {
            // 创建类的实例(对象)
            Demo7 d7 = new Demo7();
            double s = d7.area(5);
            System.out.println("圆的面积为:"+s);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    *5.9 枚举

    枚举是一种特殊的类,一般表示一组常量;
    e.g.
    public enum Season {
        Spring,Summer,Autumn,Winter;
    }
    
    • 1
    • 2
    • 3
    public class Demo8 {
        public static void main(String[] args) {
            Season s1 = Season.Spring;
            System.out.println(s1);
            System.out.println(Season.Winter.ordinal());
            for (Season k : Season.values()){
                System.out.println(k);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    interface BH{
        void show();
    }
    public enum Color implements BH{
        RED("红色",0),BLACK("黑色",1);
        String name;
        int index;
        Color(String name,int index){
            this.name = name;
            this.index = index;
        }
        public void show(){
            System.out.println(index+":"+name);
        }
    
        public static void main(String[] args) {
            Color c1 = Color.BLACK;
            System.out.println(c1.index);
            System.out.println(c1.name);
            c1.show();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    关于枚举的几点说明:
    ①枚举是一种特殊的类;
    ②枚举中可以定义属性、构造器、代码块、方法;

    *5.10设计模式

    设计模式是指在大量的实践中总结和理论化之后优选的代码结构、编程风格、及解决问题的思考方法,如同经典的棋谱。
    1、单例设计模式
    采取一定的方法保证在整个软件系统中,对某个类只能存在一个实例,
    并且该类提供一个取得其实例的方法。
    e.g.
    class Singleton{
        private Singleton(){
            System.out.println("Hello Singleton!");
        }
        // 饿汉式模式
        private static Singleton st = new Singleton();
        public static Singleton getInstance(){
            return st;
        }
    //    // 懒汉式模式
    //    private static Singleton st = null;
    //    public static Singleton getInstance(){
    //        if(st==null){
    //            st = new Singleton();
    //        }
    //        return st;
    //    }
    }
    public class Singleton_test {
        public static void main(String[] args) {
            Singleton st1 = Singleton.getInstance();
            Singleton st2 = Singleton.getInstance();
            System.out.println(st1==st2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    2、工厂模式
    定义一个用于创建对象的接口,让子类去决定实例化哪一个类。 工厂模式使一个类的实例化延迟到其子类。
    e.g.
    interface IWork{
        void doWork();
    }
    class StudentWork implements IWork{
        public void doWork(){
            System.out.println("XM is doing homework.");
        }
    }
    class TeacherWork implements IWork{
        public void doWork(){
            System.out.println("The teacher is correcting hemowork.");
        }
    }
    
    interface IWorkFactory{
        IWork getWork();
    }
    class StudentWorkFactory implements IWorkFactory{
        public IWork getWork(){
            return new StudentWork();
        }
    }
    class TeacherWorkFactory implements IWorkFactory{
        public IWork getWork(){
            return new TeacherWork();
        }
    }
    
    // 主类
    public class FactoryTest {
        public static void main(String[] args) {
            IWorkFactory i1 = new StudentWorkFactory();
            i1.getWork().doWork();
            IWorkFactory i2 = new TeacherWorkFactory();
            i2.getWork().doWork();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    3、代理模式
    为其对象提供一种代理以控制对这个对象的访问。
    e.g.
    interface Iobject{
        void action();
    }
    class A implements Iobject{
        public void action() {
            System.out.println("...被代理类开始执行...");
        }
    }
    class ProxyObject implements Iobject{
        Iobject obj;
        ProxyObject(){
            System.out.println("=====ProxyObject=====");
            obj = new A();
        }
        public void action() {
            System.out.println("++++代理类开始执行++++");
            obj.action();
        }
    }
    public class ProxyTest {
        public static void main(String[] args) {
            Iobject iobj = new ProxyObject();
            iobj.action();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    CentOS7.9.2009离线安装yum命令
    加州驾照笔试准备笔记
    音视频开发是不是C++开发中最难的细分方向?
    SpringBoot分页实现查询数据
    导电滑环材料选型要注意的因素
    计数排序(Counting Sort)详解
    8天长假快来了,Python分析【去哪儿旅游攻略】数据,制作可视化图表
    区块链技术与人工智能如何相互赋能
    STM32 CubeMX配置USB HID功能,及安装路径
    二分查找 分数 10
  • 原文地址:https://blog.csdn.net/weixin_39954229/article/details/127748073