基本概念
使用static关键字修饰成员变量表示静态的含义,此时成员变量由对象层级提升为类层级,也就是整个类只有一份并被所有对象共享,该成员变量随着类的加载准备就绪,与是否创建对象无关。
使用方式
在非静态成员方法中既能访问非静态的成员又能访问静态的成员
(成员:成员变量+成员方法,静态成员被所有对象共享)
(静态成员方法中没有this关键字,因为是可以通过类名.方式调用的)
在静态成员方法中只能访问静态成员不能访问非静态成员
(成员:成员变量+成员方法,因此此时可能还没有创建对象)
在以后的开发中只有隶属于类层级并被所有对象共享的内容才可以使用static关键字修饰(不能滥用static关键字)
package demo1.demo1.third;
public class People {
private String name;
private int age ;
//private String country ;
public static String country;
public People(){
}
public People(String name , int age ){
setName(name);
setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0 && age < 150){
this.age = age;
}else {
System.out.println("年龄不合理!");
}
}
public static String getCountry() {
return country;
}
public void setCountry(String country) {
People.country = country;
}
public void show(){
System.out.println("我是" + getName() + " , 我的年龄是:" + getAge() + " , 我的国籍是:" + getCountry());
}
}
package demo1.demo1.third;
public class PeopleTest {
public static void main(String[] args) {
//System.out.println("获取到的国籍信息是:"+ People.country);
System.out.println("获取到的国籍信息是:"+ People.getCountry());
People p1 = new People("zhangfei",30);
p1.show();
People p2 = new People("guanyu",35);
p2.show();
System.out.println("----------------------------------------------");
//p1.country = "蜀国";
p1.setCountry("蜀国");
//System.out.println("第一个对象的国籍是:" + p1.country);
//System.out.println("第二个对象的国籍是:" + p2.country);
System.out.println("第一个对象的国籍是:" + p1.getCountry());
System.out.println("第二个对象的国籍是:" + p2.getCountry());
People p3 = new People();
System.out.println("第三个对象的国籍是:" + p3.getCountry());
}
}
构造块和静态代码块
构造块:在类体中直接使用{}括起来的代码块
每创建一个对象都会执行一次构造块
静态代码块:使用static关键字修饰的构造块
(静态代码块会随着类的加载而准备就绪,会先于构造块执行)
静态代码块随着类加载时执行一次
(当需要在执行代码块之前随着类的加载做一些准备工作时,则编写代码到静态代码块中,比如:加载数据库的驱动包等)
package demo1.demo1.third;
public class BlackTest {
//当需要在执行构造方法体之前做一些准备工作时,则将准备工作的相关代码写在构造块中即可,比如对成员变量进行的统一初始化操作
{
System.out.println("构造块!"); //(2)
}
//静态代码块会随着类的加载而准备就绪,会先于构造块执行
//当需要在执行代码块之前随着类的加载做一些准备工作时,则编写代码的静态代码块中,比如加载数据库的驱动包等
static {
System.out.println("##############静态代码块!!!"); //(1)
}
//自定义构造方法
public BlackTest(){
System.out.println("=======构造方法体!"); //(3)
}
public static void main(String[] args) {
BlackTest bt = new BlackTest();
BlackTest bt1 = new BlackTest();
}
}
main方法
语法格式:
public static void main(String[] args){}
public :公有的
static : 静态的
void :表示main方法没有返回值
main :方法名
String[] args:形参列表,一维数组
package demo1.demo1.second;
public class MainTest {
public static void main(String[] args) {
System.out.println("参数数组中元素的个数是:" + args.length);
System.out.println("传递给main方法的实际参数为:");
for (int i = 0 ; i < args.length ; i++){
System.out.println("下标为:" + i + " 的形参变量数值为:" + args[i]);
}
}
}
编程实现Singleton类的封装
编程实现SingletonTest类对Singleton类进行测试,要求main方法中能得到且只能得到该类的一个对象
package demo1.demo1.second;
public class Singleton {
//2、声明本类类型的引用指向本类类型的对象,使用private static关键字共同修饰
private static Singleton singleton = new Singleton();
//1、私有化构造方法,使用private关键字修饰
private Singleton(){
}
//3、提供公有的get方法负责将对象返回出去
public static Singleton getSingleton() {
return singleton;
}
}
package demo1.demo1.second;
public class SingletonTest {
public static void main(String[] args) {
//声明Singleton类型的引用指向该类型的对象
// Singleton singleton1 = new Singleton();
// Singleton singleton2 = new Singleton();
//比较变量singleton1的数值是否与singleton2的数值是否相等 false
// System.out.println(singleton1 == singleton2);
Singleton s1 = Singleton.getSingleton();
Singleton s2 = Singleton.getSingleton();
System.out.println(s1 == s2); //true
}
}
单例设计模式的概念
在某些特殊的场合中,一个类对外提供且只提供一个对象时,这样的类叫做单例类,而设计单例的流程和思想叫走单例设计模式
单例设计模式的实现流程
1、私有化构造方法,使用private关键字修饰
2、声明本类类型的引用 指向本类类型的对象,并使用private static 关键字共同修饰
3、提供公有的get方法负责将对象返回出去,并使用public static 关键字共同修饰
单例设计模式的实现方式
单例设计模式的实现方式有两种:饿汉式和懒汉式,在以后的开发中推荐饿汉式
private static Singleton singleton = new Singleton(); //饿汉式
private static Singleton singleton = null; //懒汉式
继承的概念
当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类,让多个类吸收公共类中已有特征和行为而在多个类型只需要编写自己独有特征和行为的机制,叫做继承
在Java语言中使用extends(扩展)关键字来表示继承关系
如:
public class Worker extends Person{} //表示Worker类继承自Person类
其中Person类叫做超类、父类、基类
其中Worker类叫做派生类、子类、孩子类
使用继承提高了代码的复用性,可维护性以及扩展性,是多态的前提条件
package demo1.demo1.second;
public class Person {
//1、私有化成员变量,使用private关键字修饰
private String name;
private int age;
//3、在构造方法中调用set方法进行合理值的判断
public Person() { }
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//2、提供公有的get和set方法并在方法体中进行合理值的判断
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0 && age < 150){
this.age = age;
}
}
//自定义成员方法实现特征的打印
public void show(){
System.out.println("我是:" + getName() + " ,今年" + getAge() + "岁了");
}
//自定义成员方法描述吃饭行为
public void eat(String food){
System.out.println(food + "真好吃");
}
//自定义成员方法描述娱乐行为
public void play(String game){
System.out.println(game + "真好玩");
}
}
package demo1.demo1.second;
public class Worker extends Person{
private int salary;
public Worker(){
super(); //表示调用父类的无参构造方法,若没有加则编译器自动添加
System.out.println("Work()");
}
public Worker(String name, int age, int salary) {
super(name, age); //表示调用父类的有参构造方法
System.out.println("Work(String,int,int)");
//setName(name);
//setAge(age);
setSalary(salary);
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
if (salary > 2200){
this.salary = salary;
}else {
System.out.println("薪水不合理哦!!!");
}
}
public void work(){
System.out.println("今天的砖头有点烫手!!!");
}
}
继承的特点
1、子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承只是不能直接访问。
2、无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加代码super()的效果
3、使用继承必须满足逻辑关系:子类 is a 父类,也就是不能滥用继承。
4、Java语言中只支持单继承不支持多继承,也就是一个子类只能有一个父类,但是一个父类可以有多个子类。
方法重写
方法重写的概念
从父类中继承下来的方法不满足子类的需求时,就需要在子类中重新写一个和父类一样的方法来覆盖从父类中继承下来的版本,该方式就叫做方法的重新(Override)
方法重写的规则
1、要求方法名相同、参数列表相同以及返回值类型相同,从Java5开始允许返回子类类型。
2、要求方法的访问权限不能变小,可以相同或者变大。
3、要求方法不能抛出更大的异常(异常机制)
构造块和静态代码块
先执行父类的静态代码块,再执行子类的静态代码块
执行父类的构造块,执行父类的构造方法体
执行子类的构造块,执行子类的构造方法体。
访问控制符
注意事项
1、public修饰的成员可以在任意位置使用
2、private修饰的成员只能在本类内部使用
3、通常情况下,成员方法都使用public关键字修饰,成员变量都使用private关键字修饰。
package语句的由来
定义类时需要指定类的名称,但如果仅仅将类名作为类的唯一标识,也不可避免的出现命名冲突的问题。这会给组件复用以及团队间的合作造成很大的麻烦!
在Java语言中,用包(package)的概念来解决命名冲突的问题。
包的定义
在定义一个类时,除了定义类的名称一般还要指定一个包名,格式如下:
package 包名;
package 包名1.包名2.包名3...包名n;
为了实现项目管理,解决命名冲突以及权限控制的效果。
定义包的规范
org.apache.commons.lang.StringUtil
其中StringUtil是类名而org.apache.commons.lang是多层包名,其含义如下:org.apache表示公司或组织的信息(是这个公司(或组织)域名的反写);common表示项目的名称信息;lang表示模块的名称信息。
包的导入
使用import关键字导入
使用inport关键字导入静态成员,从Java5.0开始支持。
final
基本概念
final本意为“最终的、不可改变的”,可以修饰类、成员方法以及成员变量。
使用方式
final关键字修饰类体现在该类不能被继承
主要用于防止滥用继承,如:java.lang.String类等
final关键字修饰成员方法体现在该方法不能被重写但可以被继承
主要用于防止不经意间造成重写,如:java.text.Dateformat类中的format方法等
final关键字修饰成员变量体现在该变量必须初始化且不能改变
主要用于防止不经意间造成改变,如:java.lang.Thread类中MAX_PRIORITY等
常量的概念
在以后的开发中很少单独使用final关键字来修饰成员变量,通常使用public static final关键字共同修饰成员变量来表达常量的含义,常量的命名规范要求所有字母都要大写,不同单词之间采用下划线连接
public static final double PI = 3.14 ;