Java学习第10天

Java学习第10天

一个java文件中定义多个类

  • 只能有一个public类

  • 其他的非public类只能是默认修饰符,可以有多个非public类

  • 在public类里面可以访问非public的类(因为在同一个包下)

    package com.HQYJ.ClassDemo;
    
    //一个源文件中只能有一个public类,类名跟文件名相同
    public class Aclass {
        public static void main(String[] args) {
            Bclass b = new Bclass();
            b.best();
        }
    }
    
    //一个源文件中可以有其他类的非public(只能是默认修饰符)的类
    class Bclass{
        public void best(){
            System.out.println("B类的方法");
        }
    }
    
    class Dclass{
    
    }
    
    

内部类

定义在类中的类,就称为内部类

作用是封装,一般是自己使用的类,定义为内部类,不让别的类知道或使用这个内部类。

成员内部类(内部类定义在大括号里)

  • 内部类定义为一个成员(跟成员变量或方法同一级)
  • 内部类可以用任意访问修饰符(一般起封装作用的话用private)
  • 内部类可以直接访问外部类的属性和方法,外部类不能直接访问内部类的属性或方法,只能通过对象访问。
  • 内部类的初始化要借助外部类的对象:(Outer.)Inner inner = outer.new Inner();
package com.HQYJ.ClassDemo;

public class Outer {
    private String id = "hqyjpyy";

    public void funOuter(){
        System.out.println("外部类的方法funOuter");
    }

    private class Inner{
        public Inner(){
            System.out.println("Inner的构造方法");
        }
        private String name = "彭于晏";

        private void funInter(){
            System.out.println(id);
            System.out.println("内部类的方法funInter");
            funOuter();
        }
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.funOuter();
        Outer.Inner inner =  outer.new Inner();
        inner.funInter();
        System.out.println(inner.name);
    }
}

静态成员内部类

  • 如果成员内部类是静态的,创建内部对象的方式:Inner inner = new Inner();
  • 内部类中,只能访问外部类的静态的属性和方法
  • 在外部类中可以通过内部类的类名直接访问内部类的静态属性和方法。
package com.HQYJ.ClassDemo;

public class OuterStatic {
    private String nameOuter = "外部类属性";
    private static String nameOuterStatic = "外部类的静态属性";

    private void funOuter(){
        System.out.println("外部类的方法");
        //System.out.println(nameInner);//不能访问内部类的属性
        //funInner();//也不能访问内部类的方法
        //需要用方法间接调用,但是只能访问静态的
        Inner.funStaticInner();
        System.out.println(Inner.nameStaticInner);
    }

    private static void funStaticOuter(){
        System.out.println("外部类的静态方法");
        Inner.funStaticInner();
        System.out.println(Inner.nameStaticInner);
    }

    //静态内部类
    private static class Inner{
        private String nameInner = "内部类的属性";
        private static String nameStaticInner = "外部类的静态属性";

        private void funInner(){
            System.out.println("内部类的方法");
            System.out.println(nameOuterStatic);
            funStaticOuter();
        }

        private static void funStaticInner(){
            System.out.println("内部类的静态方法");
            System.out.println(nameOuterStatic);
            funStaticOuter();
        }
    }

    public static void main(String[] args) {
        OuterStatic outerStatic = new OuterStatic();
        Inner inner = new Inner();
        //Inner inner1 = new OuterStatic.Inner();

        inner.funInner();
        Inner.funStaticInner();
        System.out.println(Inner.nameStaticInner);
    }

}

局部内部类(定义在方法中)

  • 内部类定义在方法中
  • 内部类的对象创建只能在这个方法中,创建内部类的方式:Inner inner = new Inner();
  • 内部类可以访问外部类的属性发方法,外部类不能直接访问内部类的属性和方法,但是可以通过内部类的对象去访问。
package com.HQYJ.ClassDemo;

public class OuterLocal {
    private String nameOuter = "外部类属性";
    
    private void fun2Outer(){
        System.out.println("fun2");
    }

    private void funOuter(){
        System.out.println("外部类的方法");
        System.out.println(nameOuter);
        //局部内部类
        class Inner{
            private String nameInner = "内部类的属性";

            private void funInner(){
                System.out.println("内部类的方法");
                System.out.println(nameOuter);
                fun2Outer();
            }
        }

        //外部类不能直接访问内部类的属性
        //System.out.println(nameInner);
        //funInner();//外部类不能直接访问内部类的方法
        Inner inner = new Inner();
        inner.funInner();
        System.out.println(inner.nameInner);
    }

    public static void main(String[] args) {
        OuterLocal outerLocal = new OuterLocal();
        outerLocal.funOuter();

    }
}

匿名内部类

类只用一次,所以没有类名

一般用在接口作为方法的参数的情况。

  • Usb接口

    public interface Usb {
        void work();
    }
    
  • Computer类

    有一个方法的参数是Usb接口类型

    public class Conputer{
        //方法的参数是一个接口
        public void useUsb(Usb usb){
            usb.work();
        }
    }
    
  • 调用接口参数的方法时,直接实现接口

    这个接口的实现类没有名字,所以叫做匿名类,其他地方不可能再次用到它。

    public class ComputerTest {
        public static void main(String[] args) {
            Conputer conputer = new Conputer();
            conputer.useUsb(new Usb() {
                @Override
                public void work() {
                    System.out.println("鼠标正在工作");
                }
            });
        }
    }
    

枚举

  • 枚举的定义

    //枚举
    public enum Season {
        SPRING,SUMMER,AUTUMN,WINTER
    }
    
  • 枚举的使用

    Season spring = Season.AUTUMN;
            switch (spring){
                case SPRING -> System.out.println("春天");
                case SUMMER -> System.out.println("夏天");
                case AUTUMN -> System.out.println("秋天");
                case WINTER -> System.out.println("冬天");
            }
    

类的方法

方法就是类的行为,通过方法执行一段代码,完成特定的功能

方法的定义:

[public] [static] [abstatic] [final] 返回类型 方法名(类型 参数名,类型 参数名){

​ //方法体代码

}

方法的特性:

  • 出构造方法外,所有的方法都有返回类型,如果不需要返回值,返回类型是void;

  • 如果有返回值,方法必须有return语句(保证每一个分支都有return语句),return语句之后不能再有其他的代码。

  • 方法可以无参数、有参数、甚至可以有多个参数。

  • 可变长参数要放在方法参数的最后一个,类型的后面加三个点,可变长参数在方法中当做数组处理

  • 方法同名,参数不同,就构成重载。可变长参数的方法和固定长度参数的方法同时存在,优先调用定长参数的方法。

    package com.HQYJ.EnumDemo;
    
    public class Methoddemo {
        public void fun1() {
            System.out.println("无返回值,返回类型是void");
        }
    
        //如果有返回类型,方法体必须有return语句,返回内容必须与返回类型一致。
        public String getName() {
            String name = "";
            if (3 > 2) name = "xm";
            else name = "XM";
            return "有返回类型";
    
            /*//要保证每一个分支都有返回语句
            if (3 > 2) name = "xm";
            else return "有返回类型";*/
        }
    
        public int sum(int a, int b) {
            return a + b;
        }
    
        //类型后面有三个点的参数叫可变长参数
        //可变长的参数只能是方法的最后一个参数
        public int sum(int a,int... b){
            int sum = 0;
            sum += a;
            for (int tmp: b) {
                sum += tmp;
            }
            System.out.println(b.length);
            return sum;
        }
    
        public static void main(String[] args) {
            Methoddemo methoddemo = new Methoddemo();
            System.out.println(methoddemo.sum(1, 2, 3, 4, 5, 5, 6, 7));
        }
    }
    

传值调用和传引用调用

形参:形式参数,定义方法时给出的参数名

//a和b就是形参
public int sum(int a , int b){
    
}

实参:实际参数,调用方法时传的变量

int m = 3,n = 2;
//m和n就叫实参
sum(m,n);
  • 传值调用

    当参数类型为基本类型时,在方法里面改变形参的值,不影响实参(调用方法时copy了一份参数)

    //定义方法 
    public int sum(int a, int b) {
            int sum = a+b;
            a++;
            b--;
            return sum;
        }
    
    //调用方法
        int x = 10, y = 20;
        int sum = methoddemo.sum(x,y);
        System.out.println(sum);
        System.out.println("x:" + x+ "y:" + y);
    
  • 传引用调用

    当参数类型为引用类型(类、接口、数组),在方法里改变了这个对象的值,实参的对象的值也会跟着改变(因为他们指向堆中的同一个对象实例)

    • Student实体类
    package com.HQYJ.EnumDemo;
    
    public class Student {
        private String name;
        private int age;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        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;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "姓名是:'" + name + '\'' +
                    ", 年龄是:" + age +
                    '}';
        }
    }
    
    
    • 测试类
    package com.HQYJ.EnumDemo;
    
    public class StudentTest {
        public static void main(String[] args) {
            Student student = new Student("张三",25);
            StudentTest studentTest = new StudentTest();
            studentTest.updataStudent(student);
            System.out.println(student);
        }
    
        public void updataStudent(Student stu){
            stu.setAge(22);
        }
    }
    

方法的递归调用

方法里面调用自己,替代循环代码

(理解递归调用,知道方法被调用会在栈压入一个方法帧,直到最后一次调用方法结束,再依次出栈,返回结果)

package com.HQYJ.ClassDemo;

public class Recursion {
    public static void main(String[] args) {
        Recursion recursion = new Recursion();
        System.out.println(recursion.sumonr2n(100));
        System.out.println(recursion.sumtwo2n(10));
        System.out.println(recursion.fibonacct(24));

    }

    public int sumonr2n(int n) {
        int sum = n;
        if (n >= 1) {
            sum += sumonr2n(n - 1);
        }
        return sum;
    }

    public int sumtwo2n(int n) {
        if (n == 0) {
            return 1;
        } else {
            return n * sumonr2n(n - 1);
        }
    }

    public long fibonacct(int n) {
        if (n == 1 || n == 2) {
            return 1;
        } else{
            return fibonacct(n - 1) + fibonacct(n - 2);
        }
    }
}

你可能感兴趣的:(java,学习,jvm)