请选择 进入手机版 | 继续访问电脑版

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 77|回复: 0

[Java] java -- static, 内部类, 权限, 参数传递

[复制链接]

4306

主题

0

回帖

4306

积分

论坛元老

积分
4306
威望
0
金币
9168
贡献
0
注册时间
2022-7-17
最后登录
2022-8-27
发表于 2023-4-2 18:57:00 | 显示全部楼层 |阅读模式

人人为我,我为人人。登录后免费下载所有资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
static关键字
static是静态修饰符,一般修饰成员。被static修饰的成员属于类,不属于单个这个类的某个对象。static修饰的成员被多个对象共享。static修饰的成员属于类,但是会影响每一个对象。被static修饰的成员又叫类成员,不叫对象的成员。
static特点
被static修饰的成员变量属于类,不属于这个类的某个对象
  1. class Demo {
  2.         public static int num = 100;
  3. }
  4. class Test {
  5.         public static void main(String[] args) {
  6.                 Demo d1 = new Demo();
  7.                 Demo d2 = new Demo();
  8.                 d1.num = 200;
  9.                 System.out.println(d1.num); //结果为200
  10.                 System.out.println(d2.num); //结果为200
  11.               }
  12. }
复制代码

静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。
  1. class Demo {
  2.         //成员变量
  3.         public int num = 100;
  4.         //静态方法
  5.         public static void method(){
  6.                 //this.num; 不能使用this/super。
  7.                 //System.out.println(this.num);//报错
  8.         }
  9. }
复制代码

同一个类中,静态成员只能访问静态成员
  1. class Demo {
  2.         //成员变量
  3.         public int num = 100;
  4.         //静态成员变量
  5.         public static int count = 200;
  6.         //静态方法
  7.         public static void method(){
  8.                 //System.out.println(num); 静态方法中,只能访问静态成员变量或静态成员方法
  9.                 System.out.println(count);
  10.         }
  11. }
复制代码

static使用格式
被static修饰的成员可以并且建议通过类名直接访问。
  1. 类名.静态成员变量名
  2. 类名.静态成员方法名(参数)
  3. 对象名.静态成员变量名 // 不建议使用
  4. 对象名.静态成员方法名(参数) // 不建议使用
复制代码
  1. class Demo {
  2.         //静态成员变量
  3.         public static int num = 100;
  4.         //静态方法
  5.         public static void method(){
  6.                 System.out.println("静态方法");
  7.         }
  8. }
  9. class Test {
  10.         public static void main(String[] args) {
  11.                 System.out.println(Demo.num);
  12.                 Demo.method();
  13.         }
  14. }
复制代码

静态代码块
静态代码块:定义在成员位置,使用static修饰的代码块{ }。
  • 位置:类中方法外。
  • 执行:随着类的加载而执行且执行一次,优先构造方法的执行。

    1. public class Person {
    2.         private String name;
    3.         private int age;
    4. //静态代码块
    5.         static{
    6.                 System.out.println("静态代码块执行了");
    7.         }
    8. }
    复制代码

    定义静态常量
    开发中,我们想在类中定义一个静态常量,通常使用public static final修饰的变量来完成定义。此时变量名用全部大写,多个单词使用下划线连接。
    1. 定义格式:
    2. public static final 数据类型 变量名 = 值;
    复制代码
    1. class Company {
    2.      //比如公司名称公司地址 可能会很长很长 我们记不住 每次使用还容易打错
    3.     //这时将其定义为静态常量 方便访问 还不容易出错
    4.         public static final String COMPANY_NAME = "我的公司";
    5. }
    复制代码

    当我们想使用类的静态成员时,不需要创建对象,直接使用类名来访问即可。
    1. System.out.println(Company.COMPANY_NAME);
    复制代码

    注意:接口中的每个成员变量都默认使用public static final修饰。
    所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
    1. interface Inter {
    2.         public static final int COUNT = 100;
    3. }
    复制代码

    访问接口中的静态变量
    1. Inter.COUNT
    复制代码

    静态导入(了解)
    静态导入就是java包的静态导入,使用import static 静态导入包 , 这样可以直接使用方法名去调用静态的方法。
    静态导入格式:
    1. import static 包名.类名.方法名;
    2. import static 包名.类名.*;
    复制代码

    定义A类 如下, 含有两个静态方法 :
    1. public class A {
    2.     public static void print(Object s){
    3.         System.out.println(s);
    4.     }
    5.     public static void print2(Object s){
    6.         System.out.println(s);
    7.     }
    8. }
    复制代码

    静态导入一个类的某个静态方法 ,  使用static和类名A .方法名 , 表示导入A类中的指定方法 , 代码演示 :
    1. import static com.paopao.A.print;
    2. public class Demo {
    3.     public static void main(String[] args) {
    4.         print("test string");
    5.     }
    6. }
    复制代码

    如果有多个静态方法  , 使用static和类名A . * , 表示导入A类里的所有的静态方法, 代码演示 :
    1. import static com.paopao.A.*;
    2. public class Demo {
    3.     public static void main(String[] args) {
    4.         print("test string");
    5.         print2("test2 string");
    6.     }
    7. }
    复制代码

    权限修饰符
    在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,
  • public:公共的。
  • protected:受保护的
  • default:默认的
  • private:私有的

    不同权限的访问能力
    publicprotecteddefault(空的)private
    同一类中
    同一包中(子类与无关类)
    不同包的子类
    不同包中的无关类

    可见,public具有最大权限。private则是最小权限。
    编写代码时,如果没有特殊的考虑,建议这样使用权限:
  • 成员变量使用
    1. private
    复制代码
    ,隐藏细节。
  • 构造方法使用
    1. public
    复制代码
    ,方便创建对象。
  • 成员方法使用
    1. public
    复制代码
    ,方便调用方法。


    不加权限修饰符,其访问能力与default修饰符相同

    内部类
    将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
    成员内部类
  • 成员内部类 :定义在类中方法外的类。

    定义格式:
    1. class 外部类 {
    2.     class 内部类{
    3.     }
    4. }
    复制代码

    在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类
    1. Car
    复制代码
    中包含发动机类
    1. Engine
    复制代码
    ,这时,
    1. Engine
    复制代码
    就可以使用内部类来描述,定义在成员位置。
    代码举例:
    1. class Car { //外部类
    2.     class Engine { //内部类
    3.     }
    4. }
    复制代码

    访问特点

  • 内部类可以直接访问外部类的成员,包括私有成员。

  • 外部类要访问内部类的成员,必须要建立内部类的对象。

    创建内部公共(public)类对象格式:
    1. 外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
    复制代码

    访问演示,代码如下:
    定义类:
    1. public class Person {
    2.     private  boolean live = true;
    3.     class Heart {
    4.         public void jump() {
    5.             // 直接访问外部类成员
    6.             if (live) {
    7.                 System.out.println("心脏在跳动");
    8.             } else {
    9.                 System.out.println("心脏不跳了");
    10.             }
    11.         }
    12.     }
    13.     public boolean isLive() {
    14.         return live;
    15.     }
    16.     public void setLive(boolean live) {
    17.         this.live = live;
    18.     }
    19. }
    复制代码

    定义测试类:
    1. public class InnerDemo {
    2.     public static void main(String[] args) {
    3.         // 创建外部类对象
    4.         Person p  = new Person();
    5.         // 创建内部类对象
    6.         Person.Heart heart = p.new Heart();
    7.         // 调用内部类方法
    8.         heart.jump();
    9.         // 调用外部类方法
    10.         p.setLive(false);
    11.         // 调用内部类方法
    12.         heart.jump();
    13.     }
    14. }
    15. 输出结果:
    16. 心脏在跳动
    17. 心脏不跳了
    复制代码


    内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号
    比如,Person$Heart.class

    匿名内部类
  • 匿名内部类 :是内部类的简化写法。它的本质是一个
    1. 带具体实现的
    复制代码
    1. 父类或者父接口的
    复制代码
    1. 匿名的
    复制代码
    子类对象

    开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,
    [ol]
  • 定义子类
  • 重写接口中的方法
  • 创建子类对象
  • 调用重写后的方法
    [/ol]
    格式
    1. new 父类名或者接口名(){
    2.     // 方法重写
    3.     @Override
    4.     public void method() {
    5.         // 执行语句
    6.     }
    7. };
    复制代码

    使用方式
    以接口为例,匿名内部类的使用,代码如下:
    定义接口:
    1. public abstract class FlyAble{
    2.     public abstract void fly();
    3. }
    复制代码

    匿名内部类可以通过多态的形式接受
    1. public class InnerDemo01 {
    2.     public static void main(String[] args) {
    3.         /*
    4.                 1.等号右边:定义并创建该接口的子类对象
    5.                 2.等号左边:是多态,接口类型引用指向子类对象
    6.        */
    7.         FlyAble  f = new FlyAble(){
    8.             public void fly() {
    9.                 System.out.println("我飞了~~~");
    10.             }
    11.         };
    12.     }
    13. }
    复制代码

    匿名内部类直接调用方法
    1. public class InnerDemo02 {
    2.     public static void main(String[] args) {
    3.         /*
    4.                 1.等号右边:定义并创建该接口的子类对象
    5.                 2.等号左边:是多态,接口类型引用指向子类对象
    6.        */
    7.                new FlyAble(){
    8.             public void fly() {
    9.                 System.out.println("我飞了~~~");
    10.             }
    11.         }.fly();
    12.     }
    13. }
    复制代码

    方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递
    1. public class InnerDemo3 {
    2.     public static void main(String[] args) {
    3.         /*
    4.         1.等号右边:定义并创建该接口的子类对象
    5.         2.等号左边:是多态,接口类型引用指向子类对象
    6.        */
    7.         FlyAble  f = new FlyAble(){
    8.             public void fly() {
    9.                 System.out.println("我飞了~~~");
    10.             }
    11.         };
    12.         // 将f传递给showFly方法中
    13.         showFly(f);
    14.     }
    15.     public static void showFly(FlyAble f) {
    16.         f.fly();
    17.     }
    18. }
    复制代码

    以上可以简化,代码如下:
    1. public class InnerDemo2 {
    2.     public static void main(String[] args) {               
    3.         /*
    4.                创建匿名内部类,直接传递给showFly(FlyAble f)
    5.         */
    6.         showFly( new FlyAble(){
    7.             public void fly() {
    8.                 System.out.println("我飞了~~~");
    9.             }
    10.         });
    11.     }
    12.     public static void showFly(FlyAble f) {
    13.         f.fly();
    14.     }
    15. }
    复制代码

    引用类型的传递
    类名作为方法参数和返回值

  • 类名作为方法的形参
    方法的形参是类名,其实需要的是该类的对象
    实际传递的是该对象的【地址值】

  • 类名作为方法的返回值
    方法的返回值是类名,其实返回的是该类的对象
    实际传递的,也是该对象的【地址值】

  • 示例代码:
    1. public class Person{
    2.   public void eat(){
    3.     System.out.println("人吃了");
    4.   }
    5. }
    6. public class Test{
    7.   public static void main(String[] args){
    8.         method(new Person());
    9.                    Person p = method2();
    10.   }
    11.   pubic static void method(Person p){
    12.        p.eat();
    13.   }
    14.   public static Person method2(){
    15.             return new Person();
    16.   }
    17. }
    复制代码


    抽象类作为形参和返回值

  • 抽象类作为形参和返回值
  • 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
  • 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象

  • 示例代码:
    1. public abstract class Animal{
    2.           public abstract void eat();
    3. }
    4. public class Cat extends Animal{
    5.   public void eat(){
    6.     System.out.println("猫吃鱼");
    7.   }
    8. }
    9. public class Test{
    10.   public static void main(String[] args){
    11.       method(new Cat());
    12.    
    13.      Animal a = method2();
    14.    
    15.   }
    16.   public static void method(Animal a){
    17.        a.eat();
    18.   }
    19.   public static Animal method2(){
    20.             return new cat();
    21.   }
    22. }
    复制代码


    接口名作为形参和返回值

  • 接口作为形参和返回值
  • 方法的形参是接口名,其实需要的是该接口的实现类对象
  • 方法的返回值是接口名,其实返回的是该接口的实现类对象

  • 示例代码:
    1. public interface Fly{
    2.     public abstract void fly();
    3. }
    4. public class Bird implements Fly{
    5.   public void fly(){
    6.     System.out.println("我飞了");
    7.   }
    8. }
    9. public class Test{
    10.   public static void main(String[] args){
    11.       method(new Bird());
    12.    
    13.      Fly f = method2();
    14.    
    15.   }
    16.   public static void method(Fly f){
    17.              f.fly();
    18.   }
    19.   public static Fly method2(){
    20.             return new Bird();
    21.   }
    22. }
    复制代码


    练习
    1. 公司类
    2. ​        属性
    3. ​                总资产属性
    4. ​                所有员工属性
    5. ​        方法
    6. ​                发工资方法:从总资产中减去所有员工支出。
    7. 员工:
    8. ​        属性
    9. ​                姓名
    10. ​                工号
    11. ​                存款
    12. ​                工资
    13. 经理、厨师、服务员均为员工子类。经理在员工基础上添加奖金属性。发完工资后,请查看所有员工的存款情况.
    14. 公司类加入调整员工工资方法:返回值为void       
    15. 参数为:被调整工资的员工与调整金额(涨工资为正数、降工资为负数)。
    16. ​                方法体逻辑为,在员工工资的基础上调整相应的金额
    17. 在上边需求基础上,添加评选幸运员工(随机抽取一名员工并返回)。
    复制代码

    点击查看代码
    1. // Employee.java
    2. public class Employee {
    3.     String name;
    4.     String id;
    5.     private double deposit;
    6.     private double salary;
    7.     public Employee() {}
    8.     public Employee(String name, String id, double deposit, double salary) {
    9.         this.name = name;
    10.         this.id = id;
    11.         this.deposit = deposit;
    12.         this.salary = salary;
    13.     }
    14.     public double getDeposit() {
    15.         return deposit;
    16.     }
    17.     public void setDeposit(double deposit) {
    18.         this.deposit = deposit;
    19.     }
    20.     public double getSalary() {
    21.         return salary;
    22.     }
    23.     public void setSalary(double salary) {
    24.         this.salary = salary;
    25.     }
    26. }
    复制代码
    1. // Manager.java
    2. public class Manager extends Employee {
    3.     private double bonus;
    4.     public Manager() {
    5.     }
    6.     public Manager(String name, String id, double deposit, double salary, double bonus) {
    7.         super(name, id, deposit, salary);
    8.         this.bonus = bonus;
    9.     }
    10.     public double getBonus() {
    11.         return bonus;
    12.     }
    13.     public void setBonus(double bouns) {
    14.         this.bonus = bouns;
    15.     }
    16. }
    复制代码
    1. // Cooker.java
    2. public class Cooker extends Employee {
    3.     public Cooker() {
    4.     }
    5.     public Cooker(String name, String id, double deposit, double salary) {
    6.         super(name, id, deposit, salary);
    7.     }
    8. }
    复制代码
    1. // Waiter.java
    2. public class Waiter extends Employee{
    3.     public Waiter() {
    4.     }
    5.     public Waiter(String name, String id, double deposit, double salary) {
    6.         super(name, id, deposit, salary);
    7.     }
    8. }
    复制代码
    1. // Company.java
    2. import java.util.ArrayList;
    3. import java.util.Random;
    4. public class Company {
    5.     private double property;
    6.     private ArrayListEmployee employeeArrayList;
    7.     public Company() {
    8.     }
    9.     public Company(double property, ArrayListEmployee employeeArrayList) {
    10.         this.property = property;
    11.         this.employeeArrayList = employeeArrayList;
    12.     }
    13.     public double getProperty() {
    14.         return property;
    15.     }
    16.     public void setProperty(double property) {
    17.         this.property = property;
    18.     }
    19.     public ArrayListEmployee getEmployeeArrayList() {
    20.         return employeeArrayList;
    21.     }
    22.     public void setEmployeeArrayList(ArrayListEmployee employeeArrayList) {
    23.         this.employeeArrayList = employeeArrayList;
    24.     }
    25.     public Boolean existEmployee(){
    26.         if (employeeArrayList == null || employeeArrayList.size() == 0) {
    27.             return false;
    28.         }
    29.         return true;
    30.     }
    31.     public void printEmployeeInfo(Employee employee) {
    32.         System.out.println("工号: " + employee.id);
    33.         System.out.println("姓名: " + employee.name);
    34.         System.out.println("存款: " + employee.getDeposit());
    35.         System.out.println("工资: " + employee.getSalary());
    36.         if (employee instanceof Manager) {
    37.             System.out.println("奖金: " + ((Manager) employee).getBonus());
    38.         }
    39.         System.out.println("==============================");
    40.     }
    41.     public void showEmployeeInfo() {
    42.         ArrayListEmployee employeeArrayList = getEmployeeArrayList();
    43.         if (!existEmployee()){
    44.             System.out.println("暂无员工");
    45.             return ;
    46.         }
    47.         for (int i = 0; i  employeeArrayList.size(); i++) {
    48.             Employee employee = employeeArrayList.get(i);
    49.             printEmployeeInfo(employee);
    50.         }
    51.     }
    52.     public void showEmployeeInfo(Employee employee){
    53.         printEmployeeInfo(employee);
    54.     }
    55.     public void payingSalaries() {
    56.         if (!existEmployee()){
    57.             System.out.println("暂无员工");
    58.             return ;
    59.         }
    60.         for (int i = 0; i  employeeArrayList.size(); i++) {
    61.             Employee employee = employeeArrayList.get(i);
    62.             property -= employee.getSalary();
    63.             employee.setDeposit(employee.getDeposit() + employee.getSalary());
    64.             if (employee instanceof Manager) {
    65.                 property -= ((Manager) employee).getBonus();
    66.                 employee.setDeposit(employee.getDeposit() + ((Manager) employee).getBonus());
    67.             }
    68.         }
    69.     }
    70.     public Employee randomEmployee() {
    71.         Random r = new Random();
    72.         return employeeArrayList.get(r.nextInt(employeeArrayList.size()));
    73.     }
    74.     public void chageSalary(Employee employee, double howMuch) {
    75.         employee.setSalary(employee.getSalary() + howMuch);
    76.     }
    77. }
    复制代码

    1. // Demo.java
    2. import java.util.ArrayList;
    3. public class Demo {
    4.     public static void main(String[] args) {
    5.         ArrayListEmployee employeeArrayList = new ArrayList();
    6.         employeeArrayList.add(new Manager("张三","001",10000,2000,3000));
    7.         employeeArrayList.add(new Cooker("李四","002",1000, 2000));
    8.         employeeArrayList.add(new Waiter("王五","003",2000,2000));
    9.         Company company = new Company(1000000, employeeArrayList);
    10.         company.showEmployeeInfo();
    11.         company.payingSalaries();
    12.         company.showEmployeeInfo();
    13.         Employee employee = company.randomEmployee();
    14.         company.showEmployeeInfo(employee);
    15.         company.chageSalary(employee, -200);
    16.         System.out.println(employee.getSalary());
    17.     }
    18. }
    复制代码
  • 我爱编程论坛www.woaibiancheng.cn
    回复

    使用道具 举报

    侵权举报|手机版|我爱编程论坛 ( 蜀ICP备2022018035号-1 )

    GMT+8, 2023-10-3 20:48

    Powered by Discuz! X3.5

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表