面向对象(权限修饰符,final关键字,代码块,内部类)

一.权限修饰符

1.概述

在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,

  • public:公共的,最高权限,被public修饰的成员,在哪里都能访问
  • protected:受保护的
  • default::默认的 注意 不写权限修饰符就是默认权限,不能直接把default写出来
  • private:私有的,只能在自己的类中直接访问

2 不同权限的访问能力

publicprotecteddefault(空的)private
同类yesyesyesyes
同包不同类yesyesyesno
不同包子父类yesyesnono
不同包无关类yesnonono

public具有最大权限,private有最小权限

编写代码时,如果没有特殊的考虑,建议这样使用权限:

属性:private(封装思想)

成员方法:pulic(方便调用)

构造方法:public(方便new对象使用)

二.final关键字

1.概述

最终的

2.使用

2.1final修饰类(最终类)

public final class 类名{}

特点:被final修饰过的类不能被继承

例如:Animal类被final修饰,Dog类不能继承Animal类

public final class Animal {
    
}
public class Dog /*extends Animal*/{
}

2.2final修饰方法

修饰符 final 返回值类型 方法名(参数){
		方法体
		return 结果
}

特点:被final修饰过的方法不能被重写

final不能和abstract结合使用(原因:abstract修饰方法必须重写)

2.3final修饰局部变量

final 数据类型 变量名 =

特点:不能被二次赋值

public class Test {
    public static void main(String[] args) {
        final int i = 10;
        //i = 20;
        System.out.println("i = " + i);
        
        final int j;
        j = 10;//此处为第一次赋值
        //j = 100;
    }
}

2.4final修饰对象

final 类名 对象名 = new 类名()

特点:被final修饰的对象地址值不能改变,但是属性值可以改变

如下例:animal这个对象被final修饰,不能对animal再次指向另一个地址值,也就是地址值不能改变,如下所示idea冒红

但是可以对属性值进行更改

(https://i-blog.csdnimg.cn/direct/f5fba2fa509741d3b32e46b43c69fd70.png)

2.5final修饰成员变量

final 数据类型 变量名 =

特点:被final修饰的变量不能被二次赋值

成员变量已经初始化了,而且被final修饰了
所以jvm在编译的时候认为有参构造和set方法是二次赋值操作,所以报错

三.代码块

1.构造代码块

	{
		代码
	}

特点:优先于构造方法执行,每new一次构造代码块执行一次

public class Animal {
    
    public Animal() {
        System.out.println("我是空参构造方法");
    }

    //构造代码块
    {
        System.out.println("我是构造代码块");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Animal animal1 = new Animal();
        Animal animal2 = new Animal();

    }
}

2.静态代码块

static{
	代码
}

特点:静态代码块优先于构造代码块以及构造方法执行,而且只执行一次

public class Person {
    public Person(){
        System.out.println("我是空参构造方法");
    }

    //构造代码块
    {
        System.out.println("我是构造代码块");
    }

    //静态代码块
    static{
        System.out.println("我是静态代码块");
    }
}
public class Test02 {
    public static void main(String[] args) {
        Person P1 = new Person();
        Person P2 = new Person();

    }
}

2.1静态代码块使用场景

​ 如果需要预先初始化一些数据,这些数据只需要初始化一次,此时这些数据可以放到静态代码块中

四.内部类

​ 当一个事物的内部,还有一个部分需要完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,而这个内部的完整结构最好使用内部类

​ 当一个类内部的成员也需要用属性和行为描述时,就可以定义内部类

如下例子:A为B的外部类,B为A的内部类

class A{
    class B{
        
    }
}

1.分类

成员内部类(静态,非静态)

局部内部类

匿名内部类

1.1静态成员内部类

public class A{
      static class B{
          
      }
  }

说明:

内部类中可以定义属性,方法,构造

静态内部类可以被final(不能被继承)或者abstract(不能new)修饰

静态内部类不能调用外部的非静态成员

内部类可以被四种权限修饰符修饰

调用内部类

外部类.内部类 对象名 = new 外部类.内部类()

例子:

public class Person {
    //静态成员内部类
    static class Heart{
        public void jump(){
            System.out.println("心在跳动");
        }
    }
}

public class Test03 {
    public static void main(String[] args) {
        Person.Heart heart = new Person.Heart();
        heart.jump();
    }
}

1.2非静态成员内部类

 public class 类名{
      class 类名{
          
      }
  }

调用非静态成员

外部类.内部类 对象名 = new 外部类().new 内部类()

例子:

public class Person {
    //非静态成员内部类
    class Heart1{
        public void jump1(){
            System.out.println("心在跳动啦");
        }
    }
    //静态成员内部类
    static class Heart{
        public void jump(){
            System.out.println("心在跳动");
        }
    }
}
public class Test03 {
    public static void main(String[] args) {
        Person.Heart heart = new Person.Heart();
        heart.jump();
        Person.Heart1 heart1 = new Person().new Heart1();
        heart1.jump1();

    }
}

外部类的成员变量和内部类的成员变量以及内部类的局部变量重名时,如何进行区分

如下图所示:颜色相同的是一个变量

输出结果为:

1.3局部内部类

​ 可以定义在方法中,代码块中,构造方法中

public class Person {
    public void method(){
        /**
         * class Heart放到了method方法中
         * 所以Heart就叫做局部内部类
         */
        class Heart{
            public void jump(){
                System.out.println("心跳");
            }
        }

        new Heart().jump();
    }
}
局部内部类实际操作
1.3.1接口类型作为方法参数传递和返回

接口作为方法参数传递,我们实参传递实现类对象

接口作为方法返回值,我们返回的应该是实现类对象

public interface USB {
    public abstract void open();
}
public class Mouse implements USB{

    @Override
    public void open() {
        System.out.println("鼠标开启");
    }
}
public class Test01 {
    public static void main(String[] args) {
        //调用method01传递参数,传递实参时,
        Mouse mouse = new Mouse();
        method01(mouse);
        System.out.println("=================");
        USB usb = method02();
        usb.open();//Mouse重写的方法
    }

    /**
     * 形参为接口类型
     * @param usb
     */
    public static void method01(USB usb){//形参为接口类型 USB usb = mouse
        usb.open();
    }

    /**
     * 方法返回值类型为接口类型
     */
    public static USB method02(){
        Mouse mouse = new Mouse();
        return mouse;
    }
}

1.3.2抽象类作为方法参数和返回值

方法形参为抽象类,调用方法传递实参时需要传递子类对象

方法返回值类型为抽象类类型,返回的结果需要返回子类对象

public abstract class Animal {
    public abstract void eat();
}
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        method01(dog);
        System.out.println("=============");
        Animal animal = method02();//method02()接收的是返回回来的Dog对象
        animal.eat();
    }
    public static void method01(Animal animal){//Animal animal = dog
        animal.eat();
    }

    public static Animal method02(){
        Dog dog = new Dog();
        return dog;
    }
}
1.3.3普通类做方法参数和返回值

普通类作为方法的参数和返回值时,需要传递和返回其对象

public class Person {
    public void eat(){
        System.out.println("人要吃饭");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Person person1 = new Person();
        method01(person1);//person1在内存中保存的是地址值,0x001

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

        /*
          method02返回的person1给了method02()
          此处的method02()接收了person1对象
          然后让person2接收了person1
          此时person2和person1的地址值一样
         */
        Person person2 = method02();
        person2.eat();
    }
    public static void method01(Person person2){//Person person2 = person1
        person2.eat();
    }

    public static Person method02(){
        Person person1 = new Person();
        return person1;//person1在内存中保存的是地址值,0x002
    }
}
1.3.4局部内部类实际操作
public interface USB {
    public abstract void open();
}
public class Test01 {
    public static void main(String[] args) {
        USB usb = method();
        usb.open();
    }
    public static USB method(){
        class Mouse implements USB{
            @Override
            public void open() {
                System.out.println("鼠标开启");
            }
        }
        Mouse mouse = new Mouse();
        return mouse;
    }
}

1.4匿名内部类

​ 之前为了实现一个接口需要创建实现类实现接口,重写抽象方法,创建实现类对象,调用重写方法

​ 将四步合成一步使用匿名内部类(没有名字的局部内部类)

​ 匿名内部类代表的是子类对象或者实现类对象

当指向简单调用实现一次接口中的方法,我们就可以使用搞匿名内部类

new 接口/抽象父类(){
	重写方法
}.重写方法();

或者

接口/抽象类型 对象名 = new 接口/抽象父类(){
	重写方法
}
对象名.重写方法名();

例子

public interface USB {
    public abstract void open();
}
public class Test01 {
    public static void main(String[] args) {
        new USB() {
            @Override
            public void open() {
                System.out.println("鼠标开启");
            }
        }.open();

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

        USB usb = new USB() {
            @Override
            public void open() {
                System.out.println("鼠标开启");
            }
        };
        usb.open();

    }
}
1.4.1匿名内部类复杂用法_当参数传递
public interface USB {
    public abstract void open();
}
public class Test01 {
    public static void main(String[] args) {
        //new实现类对象,调用方法,传递实现类对象,现在实现类对象可以用匿名内部类表示
        method(new USB() {
            @Override
            public void open() {
                System.out.println("USB开启");
            }
        });
    }
    public static void method(USB usb){
        usb.open();
    }
}
1.4.2匿名内部类复杂用法_当返回值返回
public interface USB {
    public abstract void open();
}
public class Test02 {
    public static void main(String[] args) {
        USB usb = method();
        usb.open();
    }
    public static USB method(){
        return new USB() {
            @Override
            public void open() {
                System.out.println("USB打开了");
            }
        };
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值