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 -- static, 内部类, 权限, 参数传递的更多相关文章

  1. 牛客网Java刷题知识点之关键字static、static成员变量、static成员方法、static代码块和static内部类

    不多说,直接上干货! 牛客网Java刷题知识点之关键字static static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中st ...

  2. Java的内部类

    Java的内部类 首先我们来了解一下什么是内部类? 内部类是指在一个外部类的内部再定义一个类.内部类可以是静态static的,也可用public,default,protected和private修饰 ...

  3. JAVA基础——内部类详解

    JAVA内部类详解 在我的另一篇java三大特性的封装中讲到java内部类的简单概要,这里将详细深入了解java内部类的使用和应用. 我们知道内部类可分为以下几种: 成员内部类 静态内部类 方法内部类 ...

  4. Java 訪问权限控制:你真的了解 protected keyword吗?

    摘要: 在一个类的内部,其成员(包含成员变量和成员方法)是否能被其它类所訪问,取决于该成员的修饰词:而一个类是否能被其它类所訪问,取决于该类的修饰词.Java的类成员訪问权限修饰词有四类:privat ...

  5. java中内部类的积累

    放在一个类的内部的类我们就叫内部类. 二. 作用 1.内部类可以很好的实现隐藏 一般的非内部类,是不允许有 private 与protected权限的,但内部类可以 2.内部类拥有外围类的所有元素的访 ...

  6. 小白学Java:内部类

    目录 小白学Java:内部类 内部类的分类 成员内部类 局部内部类 静态内部类 匿名内部类 内部类的继承 内部类有啥用 小白学Java:内部类 内部类是封装的一种形式,是定义在类或接口中的类. 内部类 ...

  7. Java:内部类小记

    Java:内部类小记 对 Java 中的 内部类,做一个微不足道的小小小小记 首先:内部类是指在一个外部类的内部再定义一个类.内部类作为外部类的一个成员,并且依附于外部类而存在的. 成员内部类 成员内 ...

  8. Java学习--内部类(一)

    Java学习--内部类(一) 一. 内部类的定义和特点 class Outer{ privite int num = 5; class Inner{ public void Display(){ Sy ...

  9. java:访问权限

    访问权限四大类:权限从大->小 1.public:   公共权限 2.protected:  受保护权限 3.default: 包级别访问权限/默认权限 4.private:   私有权限 以p ...

  10. Java的内部类真的那么难以理解?

    01 前言 昨天晚上,我把车停好以后就回家了.回家后才发现手机落在车里面了,但外面太冷,冷到骨头都能感受到寒意——实在是不想返回一趟去取了(小区的安保还不错,不用担心被砸车玻璃),于是打定主意过几个小 ...

随机推荐

  1. Spring boot使用mybatis plus ,自己配置多数据源切换,不使用mybatis plus的自动切换数据源。如何配置?

    网上有很多springboot + mabatis 配置多数据源的文字和方案,但是我经过配置后aop都执行了,但是AbstractRoutingDataSource没有执行.所以查询结果总是使用的第一 ...

  2. centos7中通过源码安装postgresql13.6

    下载地址:https://www.postgresql.org/ftp/source/ 0.安装相关依赖库 centos依赖包下载地址:https://developer.aliyun.com/pac ...

  3. 方法(Java)

    什么是方法? 基本介绍 在其他语言中也叫函数 System.out.println();类名.对象.方法: Java方法是语句的集合,它们在一起执行一个功能 方法是解决一类问题的步骤的有序集合 方法包 ...

  4. linux 离线安装mysql 配置开机自启动

    系统版本:centos7.8 | mysql版本:5.7.35 安装配置mysql数据库 mysql数据库配置开机自启动 1. 安装配置mysql数据库 mysql版本:5.7.35 点击下载 提取码 ...

  5. 基础篇:windows常用命令

    1. windows常用系统命令 cd [进入目录] dir [列出当前目录文件] echo + 打印内容 [打印命令] echo 123 > 1.txt [打印内容到文本] type + 文件 ...

  6. redis事务和锁机制、持久化操作RDB/AOF

    一.Redis事务介绍 Redis事务是一个单独的隔离操作 :事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断.Redis事务的主要作用就是串联多个 ...

  7. Vue父子组件传值——第一次传不过去之“怪象”?

    前言:最近写Vue父子组件传值出现第一次传不过去之"怪象",以为Vue的BUG呢.然则,是自己太菜"^_^"!!!特此记录以警己 <spec-param& ...

  8. 量化交易-可视化展示(grafana)

    先上图 简单的实现了一下,效果还好,可玩性强 大概部署mysql+grafana step 1: 服务器:阿里云,ucloud啥的随意,配置也不需要什么,我的是阿里云1核1GB,足以 我用的ubunt ...

  9. 移动服务(f[i] [j] [k],这三个人,位置为a[i],j,k的最小价值)

    移动服务(f[i] [j] [k],这三个人,位置为a[i],j,k的最小价值) 题意 给出点之间到达价值,使用3个人处理一个序列,f[i] [j] [k],这三个人,每次处理序列中一个值,三个人中一 ...

  10. UG二次开发-内存访问违例

    在项目中修改路径参数后重算发生了内存访问违例的错误,经过调试,发现是下面这一行出的错 surfaceContourBuilder1.Commit(); 经过反复调试,发现这个东西不能随便放,不可以想当 ...