首页 > 编程语言 >java -- static, 内部类, 权限, 参数传递

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

时间:2023-04-02 19:12:32浏览次数:45  
标签:java -- void class static println public out

static关键字

static是静态修饰符,一般修饰成员。被static修饰的成员属于类,不属于单个这个类的某个对象。static修饰的成员被多个对象共享。static修饰的成员属于类,但是会影响每一个对象。被static修饰的成员又叫类成员,不叫对象的成员。

static特点

被static修饰的成员变量属于类,不属于这个类的某个对象

class Demo {
	public static int num = 100;
}

class Test {
	public static void main(String[] args) {
		Demo d1 = new Demo();
		Demo d2 = new Demo();
		d1.num = 200;
		System.out.println(d1.num); //结果为200
		System.out.println(d2.num); //结果为200
      	}
}

静态内容是优先于对象存在,只能访问静态,不能使用this/super。静态修饰的内容存于静态区。

class Demo {
	//成员变量
	public int num = 100;
	//静态方法
	public static void method(){
		//this.num; 不能使用this/super。
		//System.out.println(this.num);//报错
	}
}

同一个类中,静态成员只能访问静态成员

class Demo {
	//成员变量
	public int num = 100;
	//静态成员变量
	public static int count = 200;
	//静态方法
	public static void method(){
		//System.out.println(num); 静态方法中,只能访问静态成员变量或静态成员方法
		System.out.println(count);
	}
}

static使用格式

被static修饰的成员可以并且建议通过类名直接访问。

类名.静态成员变量名
类名.静态成员方法名(参数)
对象名.静态成员变量名 // 不建议使用
对象名.静态成员方法名(参数) // 不建议使用
class Demo {
	//静态成员变量
	public static int num = 100;
	//静态方法
	public static void method(){
		System.out.println("静态方法");
	}
}
class Test {
	public static void main(String[] args) {
		System.out.println(Demo.num);
		Demo.method();
	}
}

静态代码块

静态代码块:定义在成员位置,使用static修饰的代码块{ }。

  • 位置:类中方法外。
  • 执行:随着类的加载而执行且执行一次,优先构造方法的执行。
public class Person {
	private String name;
	private int age;
 //静态代码块
	static{
		System.out.println("静态代码块执行了");
	}
}

定义静态常量

开发中,我们想在类中定义一个静态常量,通常使用public static final修饰的变量来完成定义。此时变量名用全部大写,多个单词使用下划线连接。

定义格式:
public static final 数据类型 变量名 = 值;
class Company {
     //比如公司名称公司地址 可能会很长很长 我们记不住 每次使用还容易打错
    //这时将其定义为静态常量 方便访问 还不容易出错
	public static final String COMPANY_NAME = "我的公司";
}

当我们想使用类的静态成员时,不需要创建对象,直接使用类名来访问即可。

System.out.println(Company.COMPANY_NAME);

注意:接口中的每个成员变量都默认使用public static final修饰。

所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。

interface Inter {
	public static final int COUNT = 100;
}

访问接口中的静态变量

Inter.COUNT

静态导入(了解)

静态导入就是java包的静态导入,使用import static 静态导入包 , 这样可以直接使用方法名去调用静态的方法。

静态导入格式:

import static 包名.类名.方法名;
import static 包名.类名.*;

定义A类 如下, 含有两个静态方法 :

public class A {
    public static void print(Object s){
        System.out.println(s);
    }

    public static void print2(Object s){
        System.out.println(s);
    }
}

静态导入一个类的某个静态方法 , 使用static和类名A .方法名 , 表示导入A类中的指定方法 , 代码演示 :

import static com.paopao.A.print;
public class Demo {
    public static void main(String[] args) {
        print("test string");
    }
}

如果有多个静态方法 , 使用static和类名A . * , 表示导入A类里的所有的静态方法, 代码演示 :

import static com.paopao.A.*;
public class Demo {
    public static void main(String[] args) {
        print("test string");
        print2("test2 string");
    }
}

权限修饰符

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

  • public:公共的。
  • protected:受保护的
  • default:默认的
  • private:私有的

不同权限的访问能力

public protected default(空的) private
同一类中
同一包中(子类与无关类)
不同包的子类
不同包中的无关类

可见,public具有最大权限。private则是最小权限。

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

  • 成员变量使用private ,隐藏细节。
  • 构造方法使用 public ,方便创建对象。
  • 成员方法使用public ,方便调用方法。

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

内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

成员内部类

  • 成员内部类 :定义在类中方法外的类。

定义格式:

class 外部类 {
    class 内部类{

    }
}

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine 就可以使用内部类来描述,定义在成员位置。

代码举例:

class Car { //外部类
    class Engine { //内部类

    }
}

访问特点

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

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

创建内部公共(public)类对象格式:

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

访问演示,代码如下:

定义类:

public class Person {
    private  boolean live = true;
    class Heart {
        public void jump() {
            // 直接访问外部类成员
            if (live) {
                System.out.println("心脏在跳动");
            } else {
                System.out.println("心脏不跳了");
            }
        }
    }

    public boolean isLive() {
        return live;
    }

    public void setLive(boolean live) {
        this.live = live;
    }

}

定义测试类:

public class InnerDemo {
    public static void main(String[] args) {
        // 创建外部类对象 
        Person p  = new Person();
        // 创建内部类对象
        Person.Heart heart = p.new Heart();
        // 调用内部类方法
        heart.jump();
        // 调用外部类方法
        p.setLive(false);
        // 调用内部类方法
        heart.jump();
    }
}
输出结果:
心脏在跳动
心脏不跳了

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

比如,Person$Heart.class

匿名内部类

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

开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,

  1. 定义子类
  2. 重写接口中的方法
  3. 创建子类对象
  4. 调用重写后的方法

格式

new 父类名或者接口名(){
    // 方法重写
    @Override 
    public void method() {
        // 执行语句
    }
};

使用方式

以接口为例,匿名内部类的使用,代码如下:

定义接口:

public abstract class FlyAble{
    public abstract void fly();
}

匿名内部类可以通过多态的形式接受

public class InnerDemo01 {
    public static void main(String[] args) {
        /*
        	1.等号右边:定义并创建该接口的子类对象
        	2.等号左边:是多态,接口类型引用指向子类对象
       */
        FlyAble  f = new FlyAble(){
            public void fly() {
                System.out.println("我飞了~~~");
            }
        };
    }
}

匿名内部类直接调用方法

public class InnerDemo02 {
    public static void main(String[] args) {
        /*
        	1.等号右边:定义并创建该接口的子类对象
        	2.等号左边:是多态,接口类型引用指向子类对象
       */
       	new FlyAble(){
            public void fly() {
                System.out.println("我飞了~~~");
            }
        }.fly();
    }
}

方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递

public class InnerDemo3 {
    public static void main(String[] args) {
        /*
        1.等号右边:定义并创建该接口的子类对象
        2.等号左边:是多态,接口类型引用指向子类对象
       */
        FlyAble  f = new FlyAble(){
            public void fly() {
                System.out.println("我飞了~~~");
            }
        };
        // 将f传递给showFly方法中
        showFly(f);
    }
    public static void showFly(FlyAble f) {
        f.fly();
    }
}

以上可以简化,代码如下:

public class InnerDemo2 {
    public static void main(String[] args) {     	  
        /*
       	创建匿名内部类,直接传递给showFly(FlyAble f)
        */
        showFly( new FlyAble(){
            public void fly() {
                System.out.println("我飞了~~~");
            }
        });
    }

    public static void showFly(FlyAble f) {
        f.fly();
    }
}

引用类型的传递

类名作为方法参数和返回值

  • 类名作为方法的形参

    方法的形参是类名,其实需要的是该类的对象

    实际传递的是该对象的【地址值】

  • 类名作为方法的返回值

    方法的返回值是类名,其实返回的是该类的对象

    实际传递的,也是该对象的【地址值】

  • 示例代码:

    public class Person{
      public void eat(){
        System.out.println("人吃了");
      }
    }
    public class Test{
      public static void main(String[] args){
            method(new Person());
       		Person p = method2();
      }
      pubic static void method(Person p){
           p.eat();
      }
      public static Person method2(){
        	return new Person();
      }
    }
    
    

抽象类作为形参和返回值

  • 抽象类作为形参和返回值

    • 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
    • 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
  • 示例代码:

    public abstract class Animal{
      	public abstract void eat();
    }
    public class Cat extends Animal{
      public void eat(){
        System.out.println("猫吃鱼");
      }
    }
    public class Test{
      public static void main(String[] args){
          method(new Cat());
        
         Animal a = method2();
        
      }
      public static void method(Animal a){
           a.eat();
      }
      public static Animal method2(){
        	return new cat();
      }
    }
    
    

接口名作为形参和返回值

  • 接口作为形参和返回值

    • 方法的形参是接口名,其实需要的是该接口的实现类对象
    • 方法的返回值是接口名,其实返回的是该接口的实现类对象
  • 示例代码:

     public interface Fly{
        public abstract void fly();
     }
    public class Bird implements Fly{
      public void fly(){
        System.out.println("我飞了");
      }
    }
    public class Test{
      public static void main(String[] args){
          method(new Bird());
        
         Fly f = method2();
        
      }
      public static void method(Fly f){
         	f.fly();
      }
      public static Fly method2(){
        	return new Bird();
      }
    }
    

练习

公司类
​	属性
​		总资产属性
​		所有员工属性
​	方法
​		发工资方法:从总资产中减去所有员工支出。
员工:
​	属性
​		姓名
​		工号
​		存款
​		工资
经理、厨师、服务员均为员工子类。经理在员工基础上添加奖金属性。发完工资后,请查看所有员工的存款情况.

公司类加入调整员工工资方法:返回值为void	
参数为:被调整工资的员工与调整金额(涨工资为正数、降工资为负数)。
​		方法体逻辑为,在员工工资的基础上调整相应的金额

在上边需求基础上,添加评选幸运员工(随机抽取一名员工并返回)。
点击查看代码
// Employee.java
public class Employee {
    String name;
    String id;
    private double deposit;
    private double salary;

    public Employee() {}

    public Employee(String name, String id, double deposit, double salary) {
        this.name = name;
        this.id = id;
        this.deposit = deposit;
        this.salary = salary;
    }

    public double getDeposit() {
        return deposit;
    }

    public void setDeposit(double deposit) {
        this.deposit = deposit;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}
// Manager.java
public class Manager extends Employee {
    private double bonus;

    public Manager() {

    }

    public Manager(String name, String id, double deposit, double salary, double bonus) {
        super(name, id, deposit, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bouns) {
        this.bonus = bouns;
    }
}
// Cooker.java
public class Cooker extends Employee {
    public Cooker() {
    }

    public Cooker(String name, String id, double deposit, double salary) {
        super(name, id, deposit, salary);
    }
}
// Waiter.java
public class Waiter extends Employee{
    public Waiter() {
    }

    public Waiter(String name, String id, double deposit, double salary) {
        super(name, id, deposit, salary);
    }
}
// Company.java
import java.util.ArrayList;
import java.util.Random;

public class Company {
    private double property;
    private ArrayList<Employee> employeeArrayList;

    public Company() {
    }

    public Company(double property, ArrayList<Employee> employeeArrayList) {
        this.property = property;
        this.employeeArrayList = employeeArrayList;
    }

    public double getProperty() {
        return property;
    }

    public void setProperty(double property) {
        this.property = property;
    }

    public ArrayList<Employee> getEmployeeArrayList() {
        return employeeArrayList;
    }

    public void setEmployeeArrayList(ArrayList<Employee> employeeArrayList) {
        this.employeeArrayList = employeeArrayList;
    }

    public Boolean existEmployee(){
        if (employeeArrayList == null || employeeArrayList.size() == 0) {
            return false;
        }
        return true;
    }

    public void printEmployeeInfo(Employee employee) {
        System.out.println("工号: " + employee.id);
        System.out.println("姓名: " + employee.name);
        System.out.println("存款: " + employee.getDeposit());
        System.out.println("工资: " + employee.getSalary());
        if (employee instanceof Manager) {
            System.out.println("奖金: " + ((Manager) employee).getBonus());
        }
        System.out.println("==============================");
    }

    public void showEmployeeInfo() {
        ArrayList<Employee> employeeArrayList = getEmployeeArrayList();
        if (!existEmployee()){
            System.out.println("暂无员工");
            return ;
        }
        for (int i = 0; i < employeeArrayList.size(); i++) {
            Employee employee = employeeArrayList.get(i);
            printEmployeeInfo(employee);
        }
    }

    public void showEmployeeInfo(Employee employee){
        printEmployeeInfo(employee);
    }

    public void payingSalaries() {
        if (!existEmployee()){
            System.out.println("暂无员工");
            return ;
        }
        for (int i = 0; i < employeeArrayList.size(); i++) {
            Employee employee = employeeArrayList.get(i);
            property -= employee.getSalary();
            employee.setDeposit(employee.getDeposit() + employee.getSalary());
            if (employee instanceof Manager) {
                property -= ((Manager) employee).getBonus();
                employee.setDeposit(employee.getDeposit() + ((Manager) employee).getBonus());
            }
        }
    }

    public Employee randomEmployee() {
        Random r = new Random();
        return employeeArrayList.get(r.nextInt(employeeArrayList.size()));
    }

    public void chageSalary(Employee employee, double howMuch) {
        employee.setSalary(employee.getSalary() + howMuch);
    }

}

// Demo.java
import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList<Employee> employeeArrayList = new ArrayList<>();
        employeeArrayList.add(new Manager("张三","001",10000,2000,3000));
        employeeArrayList.add(new Cooker("李四","002",1000, 2000));
        employeeArrayList.add(new Waiter("王五","003",2000,2000));

        Company company = new Company(1000000, employeeArrayList);

        company.showEmployeeInfo();
        company.payingSalaries();
        company.showEmployeeInfo();
        Employee employee = company.randomEmployee();
        company.showEmployeeInfo(employee);
        company.chageSalary(employee, -200);
        System.out.println(employee.getSalary());
    }
}

标签:java,--,void,class,static,println,public,out
From: https://www.cnblogs.com/paopaoT/p/17281005.html

相关文章

  • 常用 Git 命令
    Git是我们日常工作中使用频率极高的工具,各种指令让人眼花缭乱,今天,我们就在这里总结一下它的一些基本指令,算是做一份操作笔记吧。基本指令gitadd把要提交的文件的信息添加到暂存区中。当使用gitcommit时,将依据暂存区中的内容来进行文件的提交。它通常将现有路径的当前内容......
  • 阅读-《这才是心理学》
    第一章1.什么是心理学?心理学是用来预测和分析、控制人的行为。能够更好的理解、预测别人的行为背后的原因,旨在将人的固有观念放置于科学检验之下2.心理学的用处心理学不光是学习其理论知识,更是挖掘其背后的本质学习其批判性的思维,帮助我们用于分辨各种知识主张现代心......
  • PAT Basic 1063. 计算谱半径
    PATBasic1063.计算谱半径1.题目描述:在数学中,矩阵的“谱半径”是指其特征值的模集合的上确界。换言之,对于给定的\(n\)个复数空间的特征值\({a_1+b_1i,⋯,a_n+b_ni}\),它们的模为实部与虚部的平方和的开方,而“谱半径”就是最大模。现在给定一些复数空间的特征值,请你计算......
  • 5 分钟读懂开源服务框架 Dubbo 及其最新规划
    Dubbo简介一句话定义ApacheDubbo是一款微服务开发框架,它帮助解决微服务开发中的通信问题,同时为构建企业级微服务的提供服务治理能力,Dubbo不绑定编程语言,我们的目标是为所有主流语言提供对等的微服务开发体验。基本架构Dubbo从架构图上分为数据面和控制面。在数据面,使用......
  • Vue3.0
    1.setup1.理解:Vue3.0中一个新的配置项,值为一个函数2.setup是所有CompositionAPI的表演的舞台3.组件用所用到的:数据方法等等,均要配置在setup中4.setup函数的两种返回值​1.若返回一个对象,则对象中的属性,方法在模板中均可以直接使用(重点关注!)​2.若返回......
  • 电子逻辑认知
    计算机由运算器,控制器,存储器,输入设备和输出设备组成运算器;计算机自动计算的基本原理:1计算机的自动计算过程就是执行一段预先编制好的计算程序的过程。2计算机程序是指令的有序集合。因此执行计算程序的过程实际上是逐条执行指令的过程。3指令的逐条执行是由计算机硬件来实现的,可......
  • 拦截器
    1、拦截器的基本概念拦截器是SpringBoot的一个强大的控件,它可以使得程序在进入控制器之前做一些操作,或在控制器方法完成后、甚至是在视图渲染时进行操作,常用于对控制器方法进行预处理和后处理,如进行登录、权限验证问题的处理。拦截器和过滤器的概念相似。过滤器是Ser......
  • 总序
    总序本系列是为富有远见的读者所准备的英语利器旋元佑全系列包括五本书:《旋元佑英语词汇》、《旋元佑语法》、《旋元佑语法解题》、《旋元佑英语阅读》、《旋元佑英语写作》。整个系列的设计,是为了帮助英语学习者循序渐进,彻底征服英语的不同方面。只要好好研读这五本书,读者将......
  • [每天例题]蓝桥杯 C语言 单词分析
    蓝桥杯C语言单词分析题目  题目要求1.寻找出现最多的字母和这个字母出现的次数。2.如果有多个字母出现的次数相等,输出字典序最小的那个。思路分析输入方法:方法一:1.可以通过数组来记录该单词,并为单词出现的每一个字母做上标记。2.可以采用for循环将字符串依次输......
  • 类加载机制-打破双亲委派机制
     1.什么是双亲委派机制双亲委派机制是Java类加载器的一种工作机制,它的主要思想是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这个请求委托给父类加载器去完成。如果父类加载器还存在父类加载器,则进一步向上委托,依次递归,直到委托到最顶层的启动类加......