第四章-面向对象03

 专栏目录

        第一章:学习路线图

        第二章:基础概念

        第三章:基础语法

        第四章:面向对象01

        第四章:面向对象02

        第四章:面向对象03

        第四章:面向对象04       

        第五章:常见类和对象

        第六章:异常

        第七章:集合01

        第七章:集合02

        第八章:IO

        第九章:线程

        第十章:反射


文章目录

        一、递归 

        二、访问权限、内部类、单例模式

                访问权限

                 内部类

                单例模式

        三、final

        四、抽象 

                基础知识

                抽象类和抽象方法


一、递归 

定义:方法调用自身,称之为递归方法

要求:

1.递归方法应该具备跳出逻辑:java.lang.StackOverflowError

2.调用自身时传递的参数需要具备规律

public class Java16_Object_Recursion {
    public static void main(String[] args) {
        /*
            求20以内的奇数和
            1+3+5+7+9+11+13+15+17+19
            计算是有边界的
         */
        int result = computeAP(10);
        System.out.println(result);

        System.out.println("===========================");

        /*
            阶乘:5! => (4,3,2,1) => 5*4*4*3*2*1
            0的阶乘为1
            一个大于1的数的阶乘等于这个数-1的阶乘
         */
        int result2 = computeFactorial(5);
        // int result2 = computeFactorial(50000); 报错:java.lang.StackOverflowError
        System.out.println(result2);
    }

    public static int computeAP(int num) {
        num = num % 2 == 0 ? num - 1 : num;
        if (num == 1) {
            return 1;
        } else {
            return num + computeAP(num - 2);
        }
    }

    public static int computeFactorial(int num) {
        if (num <= 1) {
            return 1;
        } else {
            return num + computeFactorial(num - 1);
        }
    }
}

二、访问权限、内部类、单例模式

访问权限

mian方法解释:由JVM调用,可以任意调用,而不需要考虑权限

public static void main(String[] args) {}
  • public:公共的,访问权限修饰符;Java源码中,公共类只能有一个,且必须和源码文件名相同
  • static:代表其为静态语法,跟当前类有关;去掉后main方法变成一个成员方法,而main方法需要以任意的方法调用它,不应该有任务限制

访问权限分类:(按权限范围由小至大排序)

  1. private:私有的,同一个类中可以使用
  2. default:默认权限,不设定权限时JVM默认提供权限(包权限/路径权限)
  3. protected:受保护的权限,子类可以访问
  4. public:公共的,任意使用
package chapter04;

public class Java17_Object_Access {
    private String name;

    public String userName;

    String sex;

    public static void main(String[] args) {
        User17 u = new User17();
        // System.out.println(u.name); 报错:'name' has private access in 'chapter04.User17
        System.out.println(u.userName);
        System.out.println(u.sex);
        System.out.println(u.age);
    }
}

class User17 {
    private String name;

    public String userName;

    String sex;

    protected int age;
    void test() {
        System.out.println(name);
        System.out.println(userName);
        System.out.println(sex);
        System.out.println(age);
    }
}

class Child17 extends User17 {
    void test() {
        System.out.println(age);
    }
}
package chapter04;

public class Java03_Object {
    public static void main(String[] args) {
        User17 user17 = new User17();
        System.out.println(user17.sex);
    }
}
package chapter03;

//import chapter04.User17;

import chapter04.Java17_Object_Access;

public class Java01_FlowControl {
        // User17 user = new User17(); 报错:'chapter04.User17' is not public in 'chapter04'. Cannot be accessed from outside package
        Java17_Object_Access user = new Java17_Object_Access();
        // System.out.println(user.name); 报错:'name' has private access in 'chapter04.Java17_Object_Access'
        System.out.println(user.userName);
        // System.out.println(user.sex); 报错:'chapter04.User17' is not public in 'chapter04'. Cannot be accessed from outside package
    }
}
package chapter04.childpackage;

import chapter04.Java17_Object_Access;

public class TestPackage {
    public static void main(String[] args) {

        Java17_Object_Access user = new Java17_Object_Access();
        // System.out.println(user.name); 报错:'name' has private access in 'chapter04.Java17_Object_Access'
        System.out.println(user.userName);
        // System.out.println(user.sex); 报错:'chapter04.User17' is not public in 'chapter04'. Cannot be accessed from outside package
        // System.out.println(user.age); 报错:Cannot resolve symbol 'age'

    }
}

 所谓访问权限,其实就是访问属性,方法的权力和限制

理解:

  1. private:同类
  2. default:同类,同包(路径)
  3. protected:同类,同包,子类
  4. public:公共的
package chapter04;

public class Java17_Object_Access_01 {

    public static void main(String[] args) {
        /*
            谁访问? Java17_Object_Access_01
            访问谁? Person17  -> super -> (实际:java.lang.Object)
         */
        person.clone();
        // 报错:'clone()' has protected access in 'java.lang.Object'
    }
}

class Person17 {
    void test() throws Exception{
        clone();
    }
}
 内部类

Java中不允许外部类使用private、protected修饰

外部类:在源码中直接声明的类

内部类:类中声明的类,当成外部类的属性使用即可,需要构建外部类对象才可以使用

class OuterClass {
    class InnerClass {

    }
}

内部类的使用

OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
单例模式

JVM默认提供的构造方法其实是公共的,无参的

public static void main(String[] args) {
    // User19 user = new User19();
    User19 user = User19.getInstance();
    User19 user1 = User19.getInstance();
    User19 user2 = User19.getInstance();
    User19 user3 = User19.getInstance();
    User19 user4 = User19.getInstance();
    User19 user5 = User19.getInstance();
}
class User19 {
    private User19() {

    }
    public static User19 getInstance() {
        returnnew User19();
    }
}

产生问题:

  1. 类的创建过程复杂
  2. 类的对象消耗资源

解决

class User19 {
    private static User19 user19 = null;
    private User19() {

    }
    public static User19 getInstance() {
        if (user19 == null) {
            user19 = new User19();
        }
        return user19;
    }
}

三、final

Java中提供了一种语法,可以在数据初始化后不被修改,使用关键字:final

  • final修饰的变量,变量的值初始化后无法修改
  • 一般将final修饰的变量称之为常量,或不可变变量
    final String name = "zhangsan";
    System.out.println(name);
    
    // name = "lisi";  报错:Cannot assign a value to final variable 'name'
  • final修饰的属性,JVM无法自动初始化,需要自己手动处理,但属性值不能发生变化
    class User20{
        // 类中声明的属性其实就是类的变量
        public final String name = "lisi";
    }
    User20 user = new User20();
    System.out.println(user.name1);
    // user.name1 = "wangwu";    报错:Cannot assign a value to final variable 'name'
    
    
    class User20{
        public final String name;
    
        public User20(String name){
           this.name = name;
        }
    }
    User20 user = new User20("wangwu");
    System.out.println(user.name);
  • final可以修饰方法,但该方法不能被子类重写
    class User20{
        public final void test() {
        }
    }
    class Child20 extends User20{
        public void test() {}
        报错:test()' cannot override 'test()' in 'chapter04.User20'; overridden method is final
    }
  • final可以修饰类,该类不能被继承,没有子类
    final class User20{
    }
    class Child20 extends User20 {
        报错:Cannot inherit from final 'chapter04.User20'
    }
  • final不允许修饰构造方法
  • final可以修改方法的参数,一旦修饰,参数无法修改
    public void test (final String name) {
        name = "lisi"; 报错:Cannot assign a value to final variable 'name'
    }

四、抽象 

基础知识

分类

  1. 抽象类:不完整的类 
    abstract class 类名
  2. 抽象方法:只有声明,没有实现 
    abstract 返回的类型 方法名(参数)

在面向对象中

  1. 分析问题:对象(具体)=>类(抽象)
  2. 编写代码:类(抽象)=>对象(具体)

简易理解:抽象相当于生活中使用不同交通工具出行,无论是开汽车,乘火车还是坐飞机,使用的交通工具不同,但本质都是为了出行。

抽象类和抽象方法

抽象类无法构建对象,因为类不完整

abstract class Person21 {}
// Person21 person21 = new Person21(); 报错:'Person21' is abstract; cannot be instantiate

如果一个类中含有抽象方法,那么这个类是抽象类

如果一个类是抽象类,它的方法不一定是抽象方法

abstract class Person21 {
    public void sleep() {
    }
}

抽象类无法直接构建对象,可以通过子类间接构建对象

abstract class Person21 {
}
class Chinese21 extends Person21 {
}
public static void main(String[] args) {
    Chinese21 chinese21 = new Chinese21();
}

如果抽象类中含有抽象方法,那么子类继承抽象类时需要重写抽象方法,将方法补充完整

abstract class Person21 {
    public abstract void eat();

    public void sleep() {
    }
}

class Chinese21 extends Person21 {
    public void eat(){
        System.out.println("开始吃饭");
    }
}

public static void main(String[] args) {
    Chinese21 chinese21 = new Chinese21();
    chinese21.eat();
}

abstract不能与final、class同时使用

abstract class Person21 {
// final abstract class Person21 {    报错:Illegal combination of modifiers: 'final' and 'abstract
    public abstract void eat();
    // public final abstract void eat();    报错:Illegal combination of modifiers: 'final' and 'abstract

    public void sleep() {
    }
}

五、接口

可以简单理解为规则

基本语法

interface 接口名称 {规则属性,规则行为}
  • 接口其实是抽象的
  • 规则属性必须为固定值不能修改
  • 属性和行为必须为公共的
  • 属性应该是静态的;行为应该是抽象的
  • 接口和类是两个层面得东西; 接口可以继承其他接口
  • 类得对象需要遵循接口,在java中,这个遵循称之为实现;类需要实现接口,而且可以实现多个接口

举例:通过USB接口提供能源

  1. 定义USB接口
    interface USBInerface {}
  2. 定义USB提供能源的接口,需要继承USB接口
    interface USBSupply extends USBInerface{
        public void powerSupply();
    }
  3. 定义USB接收能源的接口,也需要继承USB接口
    interface USBReceive extends USBInerface{
        public void powerReceive();
    }
  4. 定义接收USB提供能源的类,继承USB提供能源的接口,同时重写提供能源的方法
    class Computer implements USBSupply{
        public USBReceive usb1;
        public USBReceive usb2;
        public void powerSupply() {
            System.out.println("电脑提供能源");
            usb1.powerReceive();
            usb2.powerReceive();
        }
    }
  5. 定义接收能源后亮灯的类,继承USB接收能源的接口,同时重写接收能源的方法
    class Light implements USBReceive{
        public void powerReceive() {
            System.out.println("电灯接收能源");
        }
    }
  6. 实现提供能源和接收能源
    public static void main(String[] args) {
            Computer computer = new Computer();
            Light light1 = new Light();
            computer.usb1 = light1;
    
            Light light2 = new Light();
            computer.usb2 = light2;
            computer.powerSupply();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值