西安有哪些网站建设外包公司,中小型企业网站建设与管理考试,开发财务软件需要多少钱,鹤壁市住房和城乡建设局网站static static 常用来修饰类的成员#xff1a;成员变量、方法、嵌套类 成员变量
被static修饰#xff1a;类变量、成员变量、静态字段 在程序中只占用一段固定的内存#xff08;存储在方法区#xff09;#xff0c;所有对象共享可以通过实例、类访问 (一般用类名访问和修…static static 常用来修饰类的成员成员变量、方法、嵌套类 成员变量
被static修饰类变量、成员变量、静态字段 在程序中只占用一段固定的内存存储在方法区所有对象共享可以通过实例、类访问 (一般用类名访问和修改不建议用实例修改)但是不能通过类名访问实例变量和实例方法 没有被static修饰:实例变量 每个实例都有一份内存
package com.hxw.demo4;public class Person {public static int count 0;public int age;
}
package com.hxw.demo4;
public class Main {public static void main(String[] args) {Person.count 20;Person p1 new Person();p1.age 20;System.out.println(p1.count);Person p2 new Person();p2.age 30;System.out.println(p2.count);}
}控制台输出
20
20方法
被static修饰类方法、静态方法 可以通过实例、类访问内部不可以使用this可以直接访问类变量、类方法不可以直接访问实例变量和实例方法 没有被static修饰实例方法 只能通过实例访问不可以通过类访问内部可以使用this可以直接访问实例变量和实例方法
package com.hxw.demo4;public class Person {public static int count 0;public int age;// 实例方法public void run1(){// 实例方法中可以使用this调用其他实例方法this.run2();//实例方法可以直接访问类变量和类方法System.out.println(count);test1();System.out.println(this.age);}public void run2(){System.out.println(void run2);}public static void test1(){System.out.println(static void test1);test2();System.out.println(count);}public static void test2(){System.out.println(static void test2);}
}
package com.hxw.demo4;public class Main {public static void main(String[] args) {Person person new Person();person.age 18;person.run1();Person.test1();}
}总结
静态导入 使用了静态导入之后就可以省略类名来访问静态成员成员变量、方法、嵌套类 静态导入的经典应用
为了避免每一次都是用Math.PI,可以考虑使用静态导入其他的Math方法也是一样的道理。
成员变量的初始化
编译器会自动为未初始化的成员变量设置初始值如何手动给实例变量提供初始值 在声明中定义变量的时候直接给其设置初始值在构造方法中在构造方法内部利用this进行初始化在初始化中 这个情况看下面代码了解一下,
package com.hxw.dmeo6;public class Person {public static int count;public int age 1; //申明中public Person(){age 20;// 在构造方法中但是先执行初始化中的代码}//在初始化中{age 18;}
}
一般很少使用初始化代码,方法如下 公共初始化代码一般放到参数最多的构造方法中
package com.hxw.dmeo6;public class Person {public static int count;public int age 1; //申明中public Person(){this(0, 0);}public Person(int age){this(age, 0);}public Person(int age, int no){// 公共初始化代码一般放到参数最多的构造方法中}// //在初始化中
// {
// age 18;
// }
}
如何手动给类变量提供初始值 在声明中在静态初始化代码块中当一个类初始化的时候也就是一个类第一次被主动使用时JVM会对类进行初始化就会执行静态初始化代码块且只会执行一次。 可以有多个静态初始化块按照在源码中出现的顺序被执行 初始化块和静态初始化块
这里实际的执行顺序和自己想的不一样要先初始化完父类再初始化子类
单例模式 如果一个类设计为单例模式那么程序运行过程这个类只能创建一个实例 饿汉单例模式一开始就创建了对象懒汉单例模式等到该创建对象的时候创建对象懒汉单例模式会有线程安全问题如果三个对象同时构建实例那么会创建多个对象但是最终创建的才会赋值给instance所以总的说来还是单例模式
Rocket.class
package com.hxw.demo7;/*** 饿汉式单例模式一上来就new了一个对象*/
//public class Rocket {
// //私有的静态(唯一内存)实例变量
// private static Rocket instance new Rocket();
//
// // 构造方法私有化 在Main中就不能new Rocket()
// private Rocket(){
//
// }
//
// //公共的静态方法返回唯一的静态实例
// public static Rocket getInstance(){
// return instance;
// }
//}/*** 懒汉式单例模式*/public class Rocket {public static Rocket instace null;private Rocket(){}public static Rocket getInstance(){//用到的时候再new对象if(instace null){instace new Rocket();}return instace;}
}Main.class
package com.hxw.demo7;public class Main {public static void main(String[] args) {Rocket r1 Rocket.getInstance();Rocket r2 Rocket.getInstance();Rocket r3 Rocket.getInstance();//r1 r2 r3 都是同一个instanceSystem.out.println(r1 r2);System.out.println(r2 r3);}
}控制台输出
true
truefinal和常量
被final修饰的类不能被继承被final修饰的成员方法不能被重写被final修饰的变量只能进行一次赋值而且需要初始化如果定义的时候没有初始化那么在构造函数中一定要初始化 常量Content
常量的写法 public static final double PI 3.14159265358979323846;,一般名字全部用大写如果将基本类型或字符串定义为常量并且在编译时就能确定值编译器就会使用常量值代替各处的常量名类似于C语言的宏替换这样可以减少访问内存的次数提高代码运行的效率
嵌套类
内部类Inner Class非静态嵌套类
嵌套类定义在另一个类中的类外部类在嵌套类外层的类顶级类最外层的外部类内部类没有被static修饰的嵌套类非静态嵌套类。 跟实例变量、实例方法一样内部类与外部类的实例相关联**必须先创建外部类实例然后再用外部类实例创建内部类实例**。内部类不能定义除了除编译时常量以外的任何static成员内部类可以直接访问外部类中的所有成员即使被申明为static因为先创建了外部类实例再创建内部类实例。外部类可以直接访问内部类实例的成员变量、方法 外部类、内部类如下
package com.hxw.demo9;public class OuterClass {// 静态嵌套类static class StaticNestedClass {}// 非静态嵌套类内部类class InnerClass{}class A{class B{class C{}}}}对应的内存图如下
静态嵌套类
静态嵌套类被static修饰的嵌套类静态嵌套类在行为上就是一个顶级类只是定义的代码写在了另一个类中对比一般的顶级类静态嵌套类多了一些特殊权限 可以访问外部类中的成员即使被申明为static 什么情况使用嵌套类
情况一如果类A只用在类C内部可以考虑将类A嵌套到类C内部
封装性更好程序包更加简化增强可读性、维护性
情况二如果类A需要经常访问类C的非公共成员可以考虑将类A嵌套到类C中
另外也可以根据需要将类A隐藏起来不对外暴露
情况三如果需要经常访问非公共的实例成员而且需要现有外层后有内层的关系例如现有公司Company 后有员工Employee设计成内部类非静态嵌套类否则设计成静态嵌套类 - 如果必须现有C实例才能创建A实例那么可以将A设计为C的内部类
情况一案例
局部类
局部类定义在代码块包含{}可以在里面写代码的块中的类可以定义在方法中for循环中if语句中局部类不能定除编译时常量以外的任何static成员局部类只能访问final或者有效final只赋值一次没有被第二次赋值的局部变量局部类可以直接访问外部类的所有成员 局部类只有定义在实例相关的代码块中才能直接访问外部类中的实例成员实例变量、实例方法
由于局部类是定义在代码块中的所以其作用域也只局限于代码块中因此什么时候会用到局部类呢当一个类是在一个代码块中使用的时候
package com.hxw.demo10;public class Person {static {class A{}}{int age 10;class A{}}public void test(){for (int i 0; i 10; i) {class A{}}if(true){class A{}}else{class A{}}{class A{}}}
}抽象类
抽象方法Abstract Method
抽象方法被abstract修饰的方法 只有方法申明没有方法实现不能是private权限因为定义抽象方法的目的就是为了让子类去实现只能是实例方法而不能是类方法只能定义在抽象类接口中
package com.hxw.demo11;public abstract class Main {public static void main(String[] args) {}public abstract void test();
}
抽象类
抽象类被abstract修饰的类 可以定义抽象方法不能实例化但是可以自定义构造方法子类必须实现抽象父类中的所有抽象方法除非子类也是一个抽象类可以向非抽象类一样定义成员变量、常量、嵌套类型、初始化块、非抽象方法等也就是抽象类也可以完全不定义抽象方法
常见使用场景
抽取子类的公共实现到抽象父类中要求子类必须要单独实现的去定义成抽象方法
接口Interface
联想到日常笔记本电脑的接口不同厂商的USB长得都是一样的这是他们遵守相同的标准 APIApplication Programming Interface 应用编程接口提供给开发者调用的一组功能无需提供源码 java中的接口 一系列方法申明的集合用来定义规范、标准
抽象类abstract是通过子类继承来实现其抽象方法接口Interface是通过其他类实现该接口来实现其抽象方法
家教案例引入接口概念
有一个小孩需要应聘家教应聘要求
会教授编程会教踢足球 涉及的人群可能有在校的学生在校的老师、出租车司机
首先看没有使用接口
定义一个孩子类
package com.hxw.demo12;public class Child {private String name;private Student jiajiao;public Child(String name) {this.name name;}public String getName() {return name;}public void setName(String name) {this.name name;}public Student getJiajiao() {return jiajiao;}public void setJiajiao(Student jiajiao) {this.jiajiao jiajiao;}public void study(){jiajiao.jiaoBianCheng(this);jiajiao.jiaoZuQiu(this);}}
定义一个学生类
package com.hxw.demo12;public class Student {public void jiaoBianCheng(Child child){System.out.println(Student教 child.getName() 编程);}public void jiaoZuQiu(Child child){System.out.println(Student教 child.getName() 足球);}}
主函数
package com.hxw.demo12;public class Main {public static void main(String[] args) {Child child new Child(Jack);child.setJiajiao(new Student());child.study();}
}
如果希望老师教学生的话按照这种方式就需要再创建一个Teacher类…如果教课的人身份众多就会创建多个类要单独修改Child类中的jiajiao属性以及本类中的方法这样很繁琐但是这些类本质上都是实现了两个方法招人的要求是满足这两个要求但是对于这个人其他的特征其实不用了解。此时就可以将这两个行为定义到接口当中各种身份的家教去实现这个接口即可。
创建JiaJiaoable接口将原来Student中的方法复制过去并改写为抽象方法。
package com.hxw.demo12;public interface JiaJiaoable {public abstract void jiaoBianCheng(Child child);public abstract void jiaoZuQiu(Child child);
}
Student类、Teacher类分别实现JiaJiaoable接口中的方法
package com.hxw.demo12;public class Student implements JiaJiaoable{Overridepublic void jiaoBianCheng(Child child) {System.out.println(Student教 child.getName() biancheng);}Overridepublic void jiaoZuQiu(Child child) {System.out.println(Student教 child.getName() zuqiu);}
}
package com.hxw.demo12;public class Teacher implements JiaJiaoable{Overridepublic void jiaoBianCheng(Child child) {System.out.println(Teacher教 child.getName() biancheng);}Overridepublic void jiaoZuQiu(Child child) {System.out.println(Teacher教 child.getName() zuqiu);}
}
修改孩子类的家教属性为借口类型
package com.hxw.demo12;public class Child {private String name;private JiaJiaoable jiajiao;public Child(String name) {this.name name;}public String getName() {return name;}public void setName(String name) {this.name name;}public JiaJiaoable getJiajiao() {return jiajiao;}public void setJiajiao(JiaJiaoable jiajiao) {this.jiajiao jiajiao;}public void study(){jiajiao.jiaoBianCheng(this);jiajiao.jiaoZuQiu(this);}}
调用Main方法
package com.hxw.demo12;public class Main {public static void main(String[] args) {Child child new Child(Jack);child.setJiajiao(new Student());child.study();child.setJiajiao(new Teacher());child.study();}
}
控制台输出
Student教Jackbiancheng
Student教Jackzuqiu
Teacher教Jackbiancheng
Teacher教Jackzuqiu接口中可以定义的内容
可以定义抽象方法、常量、嵌套类型从java8开始定义 上述可以定义的内容都是隐式public的因此可以省略public关键字从java9开始可以定义private方法 常量可以省略static、final 接口中没有成员变量写出来就是常量 抽象方法可以省略abstract不能自定义构造方法、不能定义初始化块、不能实例化
Lambda
Lambda只能访问finial或者有效finial的局部变量Lambda没有引入新的作用域
定义一个OuterClass
package com.hxw.demo13;public class OuterClass {private int age 1;public class InnerClass{private int age 2;void inner(){Testable t v - {System.out.println(v);System.out.println(age);System.out.println(this.age);System.out.println(InnerClass.this.age);System.out.println(OuterClass.this.age);};t.test(3);}}public static void main(String[] args) {new OuterClass().new InnerClass().inner();}
}
方法引用