案例:编程实现People类的封装,特征有:姓名 年龄 国籍 要求提供打印方法
编程实现PeopleTest类,main方法中使用有参方式构造两个对象打印

  1. //编程实现People类的封装,特征有:姓名 年龄 国籍 要求提供打印方法
  2. public class People{
  3. private String name;
  4. private int age;
  5. private String country;
  6. public People(){ }
  7. public People(String name,int age,String country){
  8. setName(name);
  9. setAge(age);
  10. setCountry(country);
  11. }
  12. public void setName(String name){
  13. this.name=name;
  14. }
  15. public String getName(){
  16. return name;
  17. }
  18. public void setAge(int age){
  19. if(age>0 &&age<150){
  20. this.age=age;
  21. }else{
  22. System.out.println("年龄不合理哟~");
  23. }
  24. }
  25. public int getAge(){
  26. return age;
  27. }
  28. public void setCountry(String country){
  29. this.country=country;
  30. }
  31. public String getCountry(){
  32. return country;
  33. }
  34. public void show(){
  35. System.out.println("我是"+getName()+",今年"+getAge()+",来自"+getCountry());
  36. }
  37. }
  1. //编程实现PeopleTest类,main方法中使用有参方式构造两个对象打印
  2. public class PeopleTest{
  3. public static void main(String[] args){
  4. People p1=new People("张飞",30,"china");
  5. p1.show();
  6. People p2=new People("关羽",35,"china");
  7. p2.show();
  8. }
  9. }

static关键字和继承 - 图1

static关键字

1.static基本概念

  • 使用static关键字修饰成员变量表示静态的含义,此时成员变量由对象层级升为类层级,也就是整个类只有一份并被所有对象共享,该成员变量随着类的加载准备就绪,与是否创建对象无关.
  • static关键字修饰的成员可以使用引用.的方式访问,但推荐类名.的方式

static关键字和继承 - 图2

  1. //Test类中验证static关键字修饰的静态成员变量是否被所有对象共享
  2. //People类中
  3. public static String country;
  4. //Test类中
  5. p1.country="蜀国";
  6. System.out.print("第一个对象的国籍是:"+p1.country);//蜀国
  7. System.out.print("第二个对象的国籍是:"+p2.country);//蜀国

static关键字和继承 - 图3

2.static使用方式

  1. public class StaticTest{
  2. private int cnt=1;
  3. private static int ant=2;
  4. //自定义非静态的成员方法,需要使用引用.的方式访问
  5. public void show(){
  6. System.out.println(cnt);
  7. System.out.println(ant);
  8. }
  9. public static void main(String[] args){
  10. StaticTest st=new StaticTest();
  11. st.show();
  12. }
  13. }
  14. //自定义静态的成员方法,推荐使用类名.的方式访问
  15. public static void Test(){
  16. System.out.println(cnt);//静态成员方法中没有this关键字
  17. System.out.println(ant);
  18. }
  19. 在非静态成员方法中既能访问非静态的成员又能访问静态的成员
  20. (成员:成员变量+成员方法,静态成员被所有成员访问)
  21. 在静态成员方法中只能访问静态成员不能访问非静态成员
  22. (成员:成员变量+成员方法,因此此时可能还没有创建对象)
  23. 在以后的开发中只有隶属于类层级并被所有对象共享的内容才可以使用static关键字修饰.(不能滥用static关键字)

构造块和静态代码块(熟悉)

  1. //编程实现构造块和静态代码块的使用
  2. public class BlockTest{
  3. //当需要在执行构造方法体之前做一些准备工作时,
  4. //则将准备工作的相关代码写在构造块中即可
  5. //比如:对成员变量进行统一初始化操作
  6. {
  7. System.out.println("构造块!");
  8. }
  9. //自定义构造方法
  10. public BlockTest(){
  11. System.out.println("构造方法体");
  12. }
  13. //静态代码块会随着类的加载而准备就绪,会先于构造块执行
  14. static{
  15. System.out.println("静态代码快");
  16. }
  17. public static void main(String[] args){
  18. BlockTest bt=new BlockTest();
  19. BlockTest bt2=new BlockTest();
  20. }
  21. }
  22. 构造块:在类体中直接使用{}括起来的代码块.
  23. 每创建一个对象都会执行一次代码块
  24. 静态代码块:使用static 关键字修饰的构造块
  25. 静态代码块随着类加载时执行一次

static关键字和继承 - 图4 static关键字和继承 - 图5
static关键字和继承 - 图6

main方法的详解

语法格式:public static void main(String[] args){}
参数使用的举例

  1. //编程实现main方法的测试
  2. public class MainTest{
  3. public static void main(String[] args){
  4. System.out.println("参数数组中元素的个数是:"+args.length);
  5. System.out.println("传递给main方法的实际参数为:");
  6. for(int i=0;i<args.length;i++){
  7. System.out.println("下标为:"+i+"的形参变量数值为:"+args[i]);
  8. }
  9. }
  10. }

static关键字和继承 - 图7

Singleton和SingletonTest类的框架实现(重中之重)

案例:编程实现Singleton类的封装
编程实现SingletonTest类对Singleton类进行测试,要求main方法中能得到且只能得到该类的一个对象

  1. public class Singleton{
  2. //2.声明本类类型的引用指向本类类型的对象
  3. private static Singleton sin=new Singleton();
  4. //1.私有化构造方法 使用private关键字修饰
  5. private Singleton(){
  6. }
  7. //3.提供共有的get方法负责将对象返回出去,使用public static关键字
  8. public static Singleton getInstance(){
  9. return sin;
  10. }
  11. }
  1. public class SingletonTest{
  2. public static void main(String[] args){
  3. //Singleton s1=new Singleton();
  4. //Singleton s2=new Singleton();
  5. //比较变量s1和s2是否相等
  6. //System.out.println(s1==s2)//false
  7. Singleton s1=Singleton.getInstance();
  8. Singleton s2=Singleton.getInstance();
  9. System.out.println(s1==s2);//true;
  10. }
  11. }

执行流程和内存结构分析
static关键字和继承 - 图8

单例设计模式

在某种特殊场合中,一个类对外提供且只提供一个对象时,这样的类叫做单例类,而设计单例的流程和思想叫做单例设计模式
单例设计模式的实现流程

  • 私有化构造方法,使用private关键字修饰
  • 声明本类类型的引用指向本类类型的对象,并使用private static关键字共同修饰
  • 提供公有的get方法负责将对象返回出去,并使用public static 关键字共同修饰

单例设计模式的实现方式
有两种:饿汉式和懒汉式,在以后的开发中推荐使用饿汉式

  1. public class Singleton{
  2. //2.声明本类类型的引用指向本类类型的对象
  3. private static Singleton sin=new Singleton();//饿汉式
  4. //private static Singleton sin=null; //懒汉式
  5. //1.私有化构造方法 使用private关键字修饰
  6. private Singleton(){
  7. }
  8. //3.提供共有的get方法负责将对象返回出去,使用public static关键字
  9. public static Singleton getInstance(){
  10. //if(null==sin){ //懒汉式
  11. // sin=new Singleton();
  12. //}
  13. return sin;
  14. }
  15. }

继承

static关键字和继承 - 图9 static关键字和继承 - 图10

  • 当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类,让多个类吸收公共类中已有特征和行为而在多个类型中需要编写自己独有特征和行为的机制叫做继承.
  • 在java语言中使用extends(扩展)关键字来表示继承
  • 如:

public class Worker extends Person(){} 表示Worker类继承自Person类
其中Person类叫做超类 父类 基类
其中Worker类叫做派生类 子类 孩子类

继承的意义

使用继承提高了代码的复用性,可维护性以及扩展性,是多态的前提条件

  1. //编程Person类
  2. public class Person{
  3. private String name;
  4. private int age;
  5. public Person(){
  6. }
  7. public Person(String name,int age){
  8. setName(name);
  9. setAge(age);
  10. }
  11. public String getName(){
  12. return name;
  13. }
  14. public void setName(String name){
  15. this.name=name;
  16. }
  17. public int getAge(){
  18. if(age>0&&age<150){
  19. return age;
  20. }else{
  21. System.out.println("不合理");
  22. }
  23. return age;
  24. }
  25. public void setAge(int age){
  26. this.age=age;
  27. }
  28. //自定义成员方法实现特征的打印1
  29. public void show(){
  30. System.out.println(getName()+","+getAge());
  31. }
  32. public void eat(String food){
  33. System.out.println(food+"真好吃");
  34. }
  35. public void game(String game){
  36. System.out.println(game+"真好玩");
  37. }
  38. }
  1. //自定义Worker类继承Person 类
  2. public class Worker extends Person{
  3. }
  1. //Worker类的测试
  2. public class WorkerTest{
  3. public static void main(String[] args){
  4. Worker w1=new Worker();
  5. w1.show();
  6. }
  7. }

static关键字和继承 - 图11

继承的特点

  • 子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承只是不能直接访问 ```java //自定义Worker类继承Person 类 public class Worker extends Person{
    1. private int salary;
    2. public Worker(){}
    3. public Worker(String name,int age,int salary){
    4. setName(name);
    5. setAge(age);
    6. setSalary(salary);
    7. }
    8. public int getSalary(){
    9. return salary;
    10. }
    11. public void setSalary(int salary){
    12. if(salary>=2200){
    13. this.salary=salary;
    14. }else{
    15. System.out.println("不合理");
    16. }
    17. }
    18. public void work(){
    19. System.out.println("今天又是充满希望的一天!");
    20. }
    }
  1. ```java
  2. //Worker类的测试
  3. public class WorkerTest{
  4. public static void main(String[] args){
  5. Worker w1=new Worker();
  6. w1.show();
  7. System.out.println("-------");
  8. Worker w2=new Worker("张飞",30,3000);
  9. w2.show();
  10. w2.eat("豆芽");
  11. w2.game("王者荣耀");
  12. w2.work();
  13. }
  14. }
  • 无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加super()的效果

static关键字和继承 - 图12

  • 使用继承必须满足逻辑关系:子类is a 父类,也就是不能滥用继承
  • Java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父类,但一个父类可以有多个子类

    方法重写和使用

    从父类中继承下来的方法不满足子类的需求时,就需要在子类中重新写一个和父类一样的方法来覆盖从父类继承下来的版本,该方法就叫做方法的重写(Override) ```java //自定义show方法覆盖从父类中继承的版本 @override //标注/注解 用于说明下面的方法时对父类方法的重写,若没有构成重写则编译错误 public void show(){ super.show();//表示调用父类的show方法 System.out.println(“我的薪水是:”+salary); }
  1. <a name="xgVvu"></a>
  2. ## **静态块与静态代码块(笔试)**
  3. ```java
  4. package com.lagou.task08;
  5. /**
  6. * @author lijing
  7. * @date 2020/9/18 16:24
  8. * @description
  9. */
  10. public class SuperTest {
  11. {
  12. System.out.println("SuperTest类中的构造块");
  13. }
  14. static {
  15. System.out.println("SuperTest类中的静态代码块");
  16. }
  17. public SuperTest(){
  18. System.out.println("SuperTest中的构造方法体");
  19. }
  20. public static void main(String[] args) {
  21. SuperTest st=new SuperTest();
  22. }
  23. }
  1. package com.lagou.task08;
  2. /**
  3. * @author lijing
  4. * @date 2020/9/18 16:27
  5. * @description
  6. */
  7. public class SubSuperTest extends SuperTest{
  8. {
  9. System.out.println("SuperTest类中的构造块2");
  10. }
  11. static {
  12. System.out.println("SuperTest类中的静态代码块2");
  13. }
  14. public SubSuperTest(){
  15. System.out.println("SuperTest中的构造方法体2");
  16. }
  17. public static void main(String[] args) {
  18. SubSuperTest sst=new SubSuperTest();
  19. }
  20. }
  21. --------------------------------------
  22. 结果:
  23. 结果
  24. SuperTest类中的静态代码块
  25. SuperTest类中的静态代码块2
  26. SuperTest类中的构造块
  27. SuperTest中的构造方法体
  28. SuperTest类中的构造块2
  29. SuperTest中的构造方法体2
  30. 先执行父类的静态代码块,在执行子类的静态代码块
  31. 执行父类的构造块,执行父类的构造方法体
  32. 执行子类的构造块,执行子类的构造方法体