2022.5.28 关于 JAVA 类和对象(2)

目录

封装

static成员

代码块 

普通代码块(本地代码块):

构造块(实例代码块):

静态代码块:

内部类 

实例内部类:

静态内部类:

局部内部类:


封装

基本概念:

将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

了解访问修饰限定符:(YES代表可以访问)

访问范围private    默认protectepublic
1同一包中的同一类    YES    YES     YES    YES
2同一包中的不同类    YES     YES    YES
3不同包中的子类     YES    YES
4不同包中的非子类    YES

举例1:

//创建一个猫的类
class Cat{
    public int age;  
    public String name;

    private void jump(){ //这里的成员方法使用private修饰
        System.out.println(name+"被吓的跳起来");
    }
    public void bark(){  //这里的成员方法使用public修饰
        System.out.println(name+"在喵喵喵");
    }

    public Cat(int age, String name) {//构造方法
        this.age = age;
        this.name = name;
    }
}

public class Test {
    public static void main(String[] args) {
        Cat cat=new Cat(3,"小二");
        cat.jump();//正是因为jump这个成员方法使用private修饰的从而起到了封装的作用 限制了其使用范围
                   //从而使得jump()这个方法只能在 Cat这个类里使用,出了这个类便不能被使用了
         cat.bark();//而 bark这个成员方法使用的pubilc修饰,从而其使用范围更大,从而可以在main函数中使用

        
    }
}

将该串代码复制到编译器当中,我们会发现 cat.jump(); 会发生报错,正是因为我们使用了private 来修饰 jump()这一成员方法,从而对其进行了封装,使其只能在同一个包中的同一个类进行访问。


举例2:

class Cat{
    private int age; //这里的成员变量age我们使用private来进行封装,使其不能直接拿到我们的 age
    public String name;

    //既然我们在main函数中不能直接拿到我们的 age这一成员变量 我们可以提供两个成员方法解决该问题
    public int getAge() { //这是得到 age这一变量的方法
        return age;
    }

    public void setAge(int age) {//这是给age这一变量赋值的方法
        this.age = age;
    }

}
public class Test {
    public static void main(String[] args) {
        Cat cat=new Cat();
        cat.setAge(5);//这里便可以使用我们所创建的成员方法来对被封装 age 变量赋值
        System.out.println(cat.getAge()+"岁啦");//这里便可以使用我们所创建的成员方法来输出打印我们的 age变量
    }
}

我们自己可以创建两个成员方法(所谓的接口)来实现 对所被封装变量 的初始化和获取该变量。

static成员

例1:(静态成员变量)


class Student{
    //普通成员变量
    public String name;//名字
    public double score;//分数
    public int age;//年龄
    //静态成员变量  且该变量是不属于对象
    public static String classes ="2班";
    //当我们加上 final 来修饰我们的静态成员变量时 该变量便变为常量 是不可修改的
//    public static final String  classes ="2班";
}

public class Test {
    public static void main(String[] args) {
        //普通成员变量的访问
        Student student=new Student();// 创建一个类型为Student的对象student
        System.out.println(student.name);//普通成员变量一般是对象名加上 '.'来访问
        //其静态成员变量的引用 一般用其所在类的类名加上 '.'来访问
        System.out.println(Student.classes);
    }
}

当我们定义一个学生类时,例如定义一个都是2班学生的类,这个班级中的学生的姓名和分数一般都是不同的,一般使用普通成员变量,但这个2班是这个类中所有对象学生的共同点,那我们便可以使用static来定义静态成员变量classes,其值是固定的2班,且每个对象学生都是2班的。

特点:

a:静态成员变量并不属于任何一个对象,而是所有对象所共同有的。

b:可以通过对象名来访问,但一般使用类名来访问。

c:静态成员变量跟随类的加载而创建,类的卸载而销毁。


例2:(静态成员方法)

//定义一个种类都为哈士奇的狗类
class Dog{
    //普通成员变量
    public String name;//名字
    public int age;//年龄
    //静态成员变量
    public static String type="哈士奇";
    //普通成员方法
    public void bark(){
        System.out.println(name+"汪汪汪");
        fuc();//我们的静态成员方法可以被普通成员方法直接调用
    }
    //静态成员方法 假设每只哈士奇的主人都十分疼爱自己的狗狗
    public static void fuc(){
        //当我们直接在静态成员方法使用普通静态成员时会发生报错!
        //因为静态成员变量的创建是不依赖于对象的,但是name这一普通成员变量是依赖于对象的创建的
        //从而便不能直接引用我们的普通成员变量
//        System.out.println(name+"的主人很疼爱它");
        System.out.println("被主人疼爱");
    }

//    引用方式1:传一个对象的参数
//   public static void fuc(Student student) {
//       System.out.println(student.name+"的主人很疼爱它");
//   }
    //引用方式2:直接new一个对象
//       public static void fuc(){
//        Student student =new Student();
//       System.out.println(student.name+"的主人很疼爱它");
//   }

}

public class Test2 {
    public static void main(String[] args) {
        Dog.fuc();//一般直接使用类名来调用静态成员方法
    }
}

结论:

a:普通成员方法可直接调用静态成员方法。

b:静态成员方法中不能直接调用非静态的成员变量或者方法。

代码块 

普通代码块(本地代码块):

普通代码块是以 { } 的形式  定义在方法之中,但其没什么实质上的意义,所以该代码块很少见!

构造块(实例代码块):

实例代码块是以 { } 的形式 定义在方法的外部 类的内部的!其作用一般可以用来初始化实例成员变量!

静态代码块:

静态代码块是以 { } 前加上static修饰的形式来定义在方法的外部 类的内部的! 其作用一般可以用来初始化静态成员!


举例:

//定义一个四大名著书类
class Book{
    //普通成员变量
    public String name;
    public int price;
    public String type;
    public static String reputation;

    //构造方法
    public Book(String name, int price, String type) {
        this.name = name;
        this.price = price;
        this.type = type;
        System.out.println("带有三个参数的构造方法执行!");
    }

    //实例代码块
    {
        this.name="三国演义"; //可用来初始化实例成员
        System.out.println("这是实例代码块!");
    }

    //静态代码块
    static {
        reputation="四大名著";
        System.out.println("这是静态代码块!");
    }

    //普通成员方法
    public void func(){
        System.out.println("大家都喜欢读"+name);
        //普通代码块
        {
            System.out.println("这是普通代码块!");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Book book=new Book("水浒传",38,"小说");
        System.out.println("=====================================");
        Book book1 =new Book("红楼梦",36,"小说");
    }
}

输出结果为: 


我们可以发现,当我们创建一个对象的时候,该对象所对应的类中依次执行了静态代码块,实例代码块,带三个参数的构造方法 。

结论:

a:静态的最先被执行(加载了类 便会被执行) 若有多个静态的 ,看定义顺序,依次执行。

b:没有实例化对象时,只会执行静态的 且实例化多个对象时,静态的都只会执行一次!

c:其次执行实例的 若有多个实例的 ,看定义顺序,依次执行。

d:最后执行构造函数。

内部类 

定义:将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类,内部类也是封装的一种体现。


实例内部类:

class OuterClass{ //外部类
    //普通成员变量
    public int data1=1;
    private int data2=2;
    //静态成员变量
    public static int data3=3;

    class InnerClass{ //内部类
    public int data1=250;
    private int data4=4;
    //实例内部类一般不能定义静态的成员变量,如果需要定义静态成员变量,则该变量应该被final所修饰。
    public static final int data3 =5;
    //实例内部类绝对不能定义静态的成员方法!
    //内部类的构造方法
    public InnerClass(){
        System.out.println("内部类的构造方法!!!");
    }
    //内部类普通成员方法
    public void func(){
        System.out.println("实例内部类的普通方法!");
        //在内部类中调用与外部类同名的成员变量时,优先访问自己的
        System.out.println("内部类的普通成员变量data1:"+data1);
        //如果需要访问外部类的同名成员变量,格式为 外部类名.this.成员名
        System.out.println("外部类的普通成员变量data1:"+OuterClass.this.data1);
        //内部类可直接访问外部类成员
        System.out.println("外部类的普通成员变量data2:"+data2);
        System.out.println("内部类的静态成员变量data3:"+data3);
        System.out.println("外部类的静态成员变量data3:"+OuterClass.data3);

    }
    // 外部类中访问内部类成员时,得先实例化一个内部类对象!
        public void func2(){
          InnerClass innerClass=new InnerClass();
          System.out.println(innerClass.data1);
        }
    }
}

public class Test {
    public static void main(String[] args) {
        //当我们要实例化一个内部类对象时,我们必须得先实例化外部类对象
        OuterClass outerClass=new OuterClass();
        //实例化一个内部类对象的一般格式
        //外部类的类名.内部类类名 内部类对象名 = 外部类对象名.new 内部类名();
        OuterClass.InnerClass innerClass= outerClass.new InnerClass();
        //可以简写为
        OuterClass.InnerClass innerClass2= new OuterClass().new InnerClass();
        innerClass.func();
    }
}

输出结果为: 


静态内部类:

class OuterClass {
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 = 3;

    static class InnerClass {//静态内部类
        public int data4 = 4;
        private int data5 = 5;
        public static int data6 = 6;
        // 定义一个 类型为 OOuterClass 名为outer的变量;
        public OuterClass outer;

        //不带参数的内部类的构造方法
        public InnerClass() {
            System.out.println("不带参数的静态内部类的构造方法!!!");
        }

        //带参数的静态内部类的构造方法
        public InnerClass(OuterClass outerClass) {//直接传入一个外部类对象
            System.out.println("带参数的静态内部类的构造方法!!!");
            this.outer = outerClass; //将传入的外部类对象 赋给内部类中的 outer变量
        }

        public void func() {
            System.out.println("func方法执行了!");
            //静态内部类中能直接访问外部类静态成员变量或方法
            System.out.println("外部类静态成员变量data3:"+data3);
            //System.out.println(data1); 在静态内部类中不能直接访问外部类普通成员变量或方法
            //静态的 是不依赖于对象的 有可能在用该方法时 外部类对象都未生产,从而没有 data1 之类的成员变量
            //当我们需要访问时可以直接实例化一个外部类对象 从而可用 对象名.data1 的格式来直接访问
            OuterClass outerClass =new OuterClass();
            System.out.println("外部类普通成员变量data1:"+outerClass.data1);

            //或者我们在实例化内部类对象时传一个外部类对象
            //此时我们可以直接使用 outer.外部类成员变量名 来访问外部类成员变量或方法
            System.out.println("外部类普通成员变量data1:"+outer.data1);
            System.out.println("外部类普通成员变量data2:"+outer.data2);

            System.out.println("内部类普通成员变量data4:"+data4);
            System.out.println("内部类普通成员变量data5:"+data5);
            System.out.println("内部类静态成员变量data6:"+data6);
        }
        //内部类的静态成员方法
        public static void func2() {
            System.out.println("内部类的静态成员方法func2");
        }
    }
}
public class Test {
    public static void main(String[] args) {
        //当我们想实例化一个静态内部类对象时,我们知道静态的 是不依赖于对象的
        //从而格式为 外部类的类名.内部类类名 内部类对象名 = new 外部类类名.内部类类名();
        OuterClass.InnerClass innerClass =new OuterClass.InnerClass();
                                                                  //直接传入一个外部类对象
        OuterClass.InnerClass innerClass2 =new OuterClass.InnerClass(new OuterClass());
        innerClass2.func();
    }
}

输出结果:


局部内部类:

public class Test2 {
    public static void func(){
        //局部内部类只能在该方法体中使用,不能在出该方法体的外部使用,所以我们一般很少用到局部内部类
        class A{//定义在方法内部的类为局部内部类 局部内部类不能被 public static 等访问修饰限定符修饰
            public void func(){
                System.out.println("520");
            }
        }
        A a = new A();
        a.func();
    }
    public static void main(String[] args) {
        func();
    }
}

输出结果为:


以上就是类和对象的基础知识(2)的全部内容!!

如有错误或者能改进的地方 请各大佬指出 我会及时改正!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茂大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值