文章目录
前言
系列文章比较适合非科班的同学, 由浅及深, 循序渐进, 从基础开始走上大数据之路
让我们一起努力, 达成目标, 实现理想
最后恳请留下你的小❤, 点赞给我一个小小的鼓励吧
一、static关键字
1.1 概述
static是静态修饰符,一般修饰成员。被static修饰的成员属于类,不属于单个这个类的某个对象。static修饰的成员被对象共享。static修饰的成员属于类,会影响每一个对象。被static修饰的成员又叫类成员。
1.2 static特点
-
被static修饰的成员变量属于类,不属于这个类的某个对象。
也就是说,多个对象在访问或修改static修饰的成员变量时,其中一个对象将static成员变量值进行了修改,其他对象中的static成员变量值跟着改变,即多个对象共享同一个static成员变量
public class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
// 静态变量一般是类名.变量名调用, 但是实例对象也是可以访问的
d1.num = 20;
System.out.println(d1.num);
System.out.println(d2.num);
}
}
class Demo{
public static int num =10;
}
结果: 20; 20
- 静态内容是优先于对象存在,只能访问静态,不能使用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);
}
}
1.3 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();
}
}
1.4 静态原理图解
static
修饰的内容:
- 是随着类的加载而加载的,且只加载一次。
- 存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。
- 它优先于对象存在,所以,可以被所有对象共享。
1.5 代码块
静态代码块:定义在成员位置,使用static修饰的代码块{ }。
- 位置:类中方法外。
- 执行:随着类的加载而执行且执行一次,优先构造方法的执行。
- 类的加载分为三步,加载,连接,初始化,准确的来说静态代码块只有在类的初始化的时候才会执行
- 创建对象会初始化,访问静态变量会初始化,访问静态方法会初始化,创建子类对象,访问子类的静态成员会初始化
- 访问静态常量不会初始化,
举例:
public class Person {
private String name;
private int age;
//静态代码块
static{
System.out.println("静态代码块执行");
}
}
局部代码块
- 限制局部变量的作用范围
public static void main(String[] args){
//int a = 20; 这是不可以的,这里的a在main方法都有用,和下面的a冲突了
{
int a= 10;
System.out.println(a);
}
}
成员代码块
- 当创建对象的时候,就会执行,创建一个对象,就执行一个
- 优先于构造方法
1.6 定义静态常量
开发中,我们想在类中定义一个静态常量,例如数学中常用的圆周率π, 通常使用public static final修饰的变量来完成定义。此时变量名用全部大写,多个单词使用下划线连接。
格式:
public static final 数据类型 变量名 = 值;
举例:
class MyMath{
public static final double PI = 3.1415926;
}
当我们想使用类的静态成员时,不需要创建对象,直接使用类名来访问即可。
System.out.println(MyMath.PI);
注意: 接口中的每个成员变量都默认使用public static final修饰
所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
interface Inter {
public static final int COUNT = 100;
}
Inter.COUNT
1.7 静态导入
静态导入就是java包的静态导入,使用import static 静态导入包 , 这样可以直接使用方法名去调用静态的方法
格式:
import static 包名.类名.方法名;
import static 包名.类名.*;
举例:
定义A类 如下, 含有两个静态方法 :
package net.csdn;
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 net.csdn.A.print; //导包
public class Demo {
public static void main(String[] args) {
print("test string");
}
}
如果有多个静态方法 , 使用static和类名A . * , 表示导入A类里的所有的静态方法
import static net.csdn.A.*;
public class Demo {
public static void main(String[] args) {
print("test string");
print2("test2 string");
}
}
二、内部类
2.1 概述
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
2.2 成员内部类
成员内部类 :定义在类中方法外的类。
格式:
class 外部类 {
class 内部类{
}
}
在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car
中包含发动机类Engine
,这时,Engine
就可以使用内部类来描述,定义在成员位置。
例如:
class Car { //外部类
class Engine { //内部类
}
}
访问特点
-
内部类可以直接访问外部类的成员,包括私有成员。
-
外部类要访问内部类的成员,必须要建立内部类的对象。
创建内部类对象格式:
外部类名.内部类名 对象名 = 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
2.3 匿名内部类
匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的
父类或者父接口的
匿名的
子类对象。
开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,
- 定义子类
- 重写接口中的方法
- 创建子类对象
- 调用重写后的方法
我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。
前提:
存在一个类或者接口,这里的类可以是具体类也可以是抽象类。
格式:
new 父类名或者接口名(){
// 并不是父类或者接口可以new了, 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(){
@Override
public void fly() {
System.out.println("芜湖起飞");
}
};
}
}
匿名内部类直接调用方法
public class InnerDemo02 {
public static void main(String[] args) {
new FlyAble(){
public void fly() {
System.out.println("芜湖起飞");
}
}.fly(); // 实现类调用重写方法
}
}
方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递
public class InnerDemo3 {
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();
}
}
三、引用类型的传递
3.1 类名作为方法参数和返回值
-
类名作为方法的形参
方法的形参是类名,其实需要的是该类的对象,实际传递的是该对象的
地址值
-
类名作为方法的返回值
方法的返回值是类名,其实返回的是该类的对象, 实际传递的,也是该对象的
地址值
举例:
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();
}
}
3.2 抽象类作为形参和返回值
-
方法的形参是抽象类名,其实需要的是该抽象类的子类对象
-
方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
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();
}
}
3.3 接口名作为形参和返回值
-
方法的形参是接口名,其实需要的是该接口的实现类对象
-
方法的返回值是接口名,其实返回的是该接口的实现类对象
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();
}
}
四、综合练习
4.1 综合问题
abstract
关键字是什么可以修饰哪些?
抽象修饰符,可以修饰类、方法
final
关键字是什么可以修饰哪些?
最终修饰符,可以修饰类、方法、成员变量、局部变量
static
关键字是什么可以修饰哪些?
静态修饰符,可修饰内部类、方法、成员变量
private
能不能和abstract
一起使用?
不能,子类必须重写父类或接口的方法,而private子类无法直接访问
final
能不能和abstract
一起使用?
不能,final修饰的类不能被继承,抽象的子类必须继承后才能使用
final修饰的方法不能被重写,抽象类的的方法子类必须全部重写
static
能不能和abstract
一起使用?
不可以,如果一起使用,就会出现可以类名.调用的抽象方法,这个方法没有方法体,没有意义
static
能不能和final
一起使用?
可以,静态常量就是
4.2 代码题
按照以下要求定义类
员工类
属性
id
name
基本工资
行为
工作 抽象
计算工资 抽象
经理类
属性
id
name
基本工资
管理工资
行为
工作
计算工资 基本工资+管理工资
程序员
属性
id
name
基本工资
项目奖金
行为
工作
计算工资 基本工资+项目奖金
公司类
属性
公司名称
行为
查看员工工资(员工){
公司名称:xxx公司
员工的工号:38250
员工的姓名:柳岩
员工的职位:经理
员工的工资:11111.00
}
测试类
创建公司对象 指定公司名称
调用查看员工工资的方法 查看一个经理的工资
调用查看员工工资的方法 查看一个程序员的工资
参考:
//公司
public class Company {
String mingCheng;
public Company() {
}
public Company(String mingCheng) {
this.mingcheng = mingCheng;
}
public void check(Employee e) {
System.out.println("公司名称: " + mingcheng + "公司");
System.out.println("员工的工号: " + e.getId());
System.out.println("员工的姓名: " + e.getNam());
if (e instanceof Manager) {
Manager m = (Manager) e;
System.out.println("员工的职位: 经理");
System.out.println("员工的工资: " + m.calcuateSalary());
}
if (e instanceof Programmer) {
Programmer p = (Programmer) e;
System.out.println("员工的职位: 程序员");
System.out.println("员工的工资: " + p.calcuateSalary());
}
}
}
//员工抽象类
public abstract class Employee {
private String id;
private String nam;
private double salary;
public Employee() {
}
public Employee(String id, String nam, double salary) {
this.id = id;
this.nam = nam;
this.salary = salary;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNam() {
return nam;
}
public void setNam(String nam) {
this.nam = nam;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"id='" + id + '\'' +
", nam='" + nam + '\'' +
", salary=" + salary +
'}';
}
public abstract void work();
public abstract double calcuateSalary();
}
//经理
public class Manager extends Employee{
private double guanLiFei;
public Manager() {
}
public Manager(String id, String nam, double salary, double guanLiFei) {
super(id, nam, salary);
this.guanLiFei = guanLiFei;
}
public double getGuanLiFei() {
return guanLiFei;
}
public void setGuanLiFei(double guanLiFei) {
this.guanLiFei = guanLiFei;
}
@Override
public void work() {
System.out.println("经理工作");
}
@Override
public double calcuateSalary() {
double total = guanLiFei+getSalary();
return total;
}
}
//程序员
public class Programmer extends Employee {
private double jiangJin;
public Programmer() {
}
public Programmer(String id, String nam, double salary, double jiangJin) {
super(id, nam, salary);
this.jiangJin = jiangJin;
}
public double getJiangJin() {
return jiangJin;
}
public void setJiangJin(double jiangJin) {
this.jiangJin = jiangJin;
}
@Override
public void work() {
System.out.println("程序员工作");
}
@Override
public double calcuateSalary() {
double total = jiangJin+getSalary();
return total;
}
}
//测试类
public class Test {
public static void main(String[] args) {
Company cp = new Company("CSDN");
Manager m = new Manager("001", "张三", 10000, 10000);
Programmer p = new Programmer("002", "小四", 2000, 5000);
cp.check(m);
System.out.println("--------------");
cp.check(p);
}
}
总结
左上角主页里面有所有系列文章喔!
消除贫穷的最好办法就是和我一起学大数据,加油,奥利给!
看到这里点个赞吧!