static关键字和继承

来自拉钩教育-JAVA就业集训营

People类和测试类的实现

  • 案列题目
    • 编程实现People类的封装,特征有:姓名、年龄、国际,要求提供打印所有特征的方法。
    • 编程试下PeopleTest类,main方法中使用有参方式构造两个对象并打印。
/*

*/
public class People {
    
    // 1.私有化成员变量,使用private关键字修饰
    private String name;
    private int age;
    private String county;
    
    // 3.在构造方法中调用set方法进行合理值的判断
    public People(){}
    public People(String name, int age, String county) {
        setName(name);
        setAge(age);
        setCounty(county);
    }
    
    // 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;
        } else {
            System.out.println("年龄不合理哦!!!");
        }
    }
    
    public String getCounty() {
        return county;
    }
    public void setCounty(String county) {
        this.county = county;
    }
    
    // 
    public void show(){
        System.out.println("我是" + getName() + ",今年" + getAge() + "岁了,来自" + getCounty());
    }
    
}
/*
    
*/
public class PeopleTest {
    public static void main(String[] args) {
        // 1.使用有参方式构造两个People类型的对象并打印特征
        People p1 = new People("zhangfei", 30, "China");
        p1.show();
        
        People p2 = new People("guanyu", 35, "China");
        p2.show();
    }
}

static关键字的基本概念

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

static关键字的使用方式

  • 在非静态成员方法中既能访问非静态的成员又能访问静态成员。
    • (成员:成员变量 + 成员方法, 静态成员被所有对象共享)
  • 静态成员方法中只能访问静态成员不能访问非静态成员。
    • (成员:成员变量 + 成员方法, 因为此时可能还没有创建对象)
  • 在以后的开发中只有隶属于类层级并被所有对象共享的内容才可以使用static关键字修饰。(不能滥用static关键字)

构造块和静态代码块

  • 构造块:在类体中直接使用{}括起来的代码块。
  • 每创建一个对象都会执行一次构造块。
  • 静态代码快:使用static关键字修饰的构造块。
  • 静态代码块随着类加载时执行一次。
/*
    编程实现构造块和静态代码块的使用
*/
public class BlockTest {
    
    // 当需要在执行构造方法体之前做一些准备工作时,则将准备工作的相关代码卸载构造块中即可,比如:对成员变量进行的统一初始化操作。
    {
        System.out.println("构造块!"); // (2)
    }
    
    // 静态代码块会随着类的加载而准备就绪,会先于构造块执行
    // 当需要在执行代码块之前随着类的加载做一些准备工作时,则编写代码到静态代码块中,比如:加载数据库的驱动包等。
    static {
        System.out.println("#############静态构造块!"); // (1)
    }
    
    // 自定义构造方法
    public  BlockTest() {
        System.out.println("====构造方法体!"); // (3)
    }
    
    public static void main(String[] args) {
        BlockTest bt = new BlockTest();
        BlockTest bt2 = new BlockTest();    
    }
}

main方法的详解

  • 语法格式:
    public static void main(String[] args) {}
/*
    编程实现main方法的测试
*/
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 类的封装
    • 编程实现 SingletonTest 类对 Singleton 类进行测试,要求main方法中能得到且只能得到该类的一个对象。
/*
    编程实现 Singleton 类的封装
*/
public class Singleton {
    
    // 2.声明本类类型的引用指向本类类型的对象,使用private static关键字共同修饰
    private static Singleton sin = new Singleton();
    
    // 1.私有化构造方法,使用private关键字修饰
    private Singleton (){}
    
    // 3.提供公有的get方法负责将对象返回出去,使用public static关键字共同修饰
    public static Singleton getInstance() {
        return sin;
    }
}
/*
 编程实现 Singleton 类的测试
*/
public class SingletonTest {
    
    public static void main(String[] args) {
        // 1.声明Singleton类型的引用指向该类型的对象
        // Singleton s1 = new Singleton();
        // Singleton s2 = new Singleton();
        // System.out.println(s1 == s2); // 比较变量s1的数值是否与变量s2的数值相等 false
        
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1 == s2);
        
    }
}

单例设计模式的概念

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

单例设计模式的实现流程

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

单例设计模式的实现方式

  • 单例设计模式的实现方式有两种:饿汉式和懒汉式,在以后有的开发中推荐饿汉式。
  • 选择饿汉式,是因为多线程抢占共享资源的问题。
  • 饿汉式
/*
    编程实现 Singleton 类的封装
*/
public class Singleton {
    
    // 2.声明本类类型的引用指向本类类型的对象,使用private static关键字共同修饰
    private static Singleton sin = new Singleton();
    
    // 1.私有化构造方法,使用private关键字修饰
    private Singleton (){}
    
    // 3.提供公有的get方法负责将对象返回出去,使用public static关键字共同修饰
    public static Singleton getInstance() {
        return sin;
    }
}
  • 懒汉式
/*
    编程实现 Singleton 类的封装
*/
public class Singleton {
    
    // 2.声明本类类型的引用指向本类类型的对象,使用private static关键字共同修饰
    private static Singleton sin = null;
    
    // 1.私有化构造方法,使用private关键字修饰
    private Singleton (){}
    
    // 3.提供公有的get方法负责将对象返回出去,使用public static关键字共同修饰
    public static Singleton getInstance() {
        if (null == sin) {
            sin = new Singleton();
        }
        return sin;
    }
}

继承的由来

  • 当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类,让多个类吸收公共类中已有特征和行为而在多个类型只需要编写自己独有特征和行为的机制,叫做继承。

继承的概念

  • 在java语言中使用extends(扩展)关键字来表示继承关系。
  • 如:
    • public class Worder extends Person {} - 百世Worker类继承自Person类
    • 其中 Person 类叫做超类、父类、基类。
    • 其中Worker类叫做派生类、子类、孩子类。
  • 使用继承提高了代码的复用性,可维护性及扩展性,是多态的前提条件。

继承的特点

  • 子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承只是不能直接访问。
  • 无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加代码super()的效果。
  • 使用继承必须满足逻辑关系:子类 is a 父类,也就是不能滥用继承。
  • Java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父类,但一个父类可以有多个子类。
  • person类
/*
    编程实现 Person 类的封装
*/
public class Person {
    
    // 1.私有化成员变量,使用private关键字修饰
    private String name;
    private int age;
    
    // 3.在构造方法中调用set方法进行合理值的判断
    public Person() {
        System.out.println("Person()");
    }
    public Person(String name, int age) {
        System.out.println("Person(String, int)");
        setName(name);
        setAge(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;
        } else {
            System.out.println("年龄不合理");
        }
    }
    
    // 自定义成员方法实现特征的打印
    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 + "真好玩!");
    }
}
  • Worker 类
/*
    自定义Worker类继承自Person类
*/
public class Worker extends Person {
    
    private int salary;
    
    public Worker(){
        super(); // 表示调用父类的无参构造方法,若没有加则编译器自动添加
        System.out.println("Worker()");
    }
    public Worker(String name, int age, int salary){
        super(name, age); // 表示调用父类的无参构造方法
        System.out.println("Worker(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("今天的砖头有点烫手~~");
    }
    
}
  • WorkerTest类
/*
    编程实现Worker类的测试
*/
public class WorkerTest {
    
    public static void main(String[] args) {
        
        // 1.使用无参范式构造Worker类型的对象并打印特征
        Worker w1 = new Worker();
        w1.show();
        
        System.out.println("-----------------------------");
        // 2.使用有参的方式构造Worker类型的对象并打印特征
        Worker w2 = new Worker("zhangfei", 30, 3000);
        w2.show();
        // 调用成员方法测试
        w2.eat("豆芽");
        w2.play("王者荣耀");
        w2.work();
        
    }
}
  • Teacher类
/*
    编程实现Teacher类继承Person类
*/
public class Teacher extends Person {
}
  • TeacherTest类
/*
    编程实现Teacher类的测试
*/
public class TeacherTest {
    
    public static void main(String[] args) {
        
        // 1.使用无参范式构造Teacher类型的对象并打印特征
        Teacher t1 = new Teacher();
        t1.show();
    }
}

方法重写的概念

  • 从父类中继承下来的方法不满足子类的需要求,就需要在子类中重新写一个和父类一样的方法来覆盖从父类中继承下来的版本,该方式就叫做方法重写(Override)。

方法重写的原则

  • 要求方法名相同、参数列表相同以及返回值类型相同,从Java5开始允许返回子类类型。

  • 要求方法的访问权限不能变小,可以相同或者变大。

  • 要求方法不能抛出更大的异常(异常机制)。

  • person类(父类)

/*
    编程实现 Person 类的封装
*/
public class Person {
    
    // 1.私有化成员变量,使用private关键字修饰
    private String name;
    private int age;
    
    // 3.在构造方法中调用set方法进行合理值的判断
    public Person() {
        System.out.println("Person()");
    }
    public Person(String name, int age) {
        System.out.println("Person(String, int)");
        setName(name);
        setAge(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;
        } else {
            System.out.println("年龄不合理");
        }
    }
    
    // 自定义成员方法实现特征的打印
    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 + "真好玩!");
    }
}
  • Worker类(子类):重写show()方法
/*
    自定义Worker类继承自Person类
*/
public class Worker extends Person {
    
    private int salary;
    
    public Worker(){
        super(); // 表示调用父类的无参构造方法,若没有加则编译器自动添加
        System.out.println("Worker()");
    }
    public Worker(String name, int age, int salary){
        super(name, age); // 表示调用父类的无参构造方法
        System.out.println("Worker(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("今天的砖头有点烫手~~");
    }
    
    // 自定义show方法覆盖从父类中继承的版本
    @Override // 标注 / 注解,用于说明下面的方法是对父类方法的重写,若没有构成重写则编译报错
    public void show() {
        super.show();
        System.out.println("我的薪水是:" + getSalary());
    }
}

构造代码块与静态代码块执行顺序

  • 先执行父类的静态代码块,再执行子类的静态代码块。
  • 执行父类的构造块,执行父类的构造方法体。
  • 执行子类的构造块,执行子类的构造方法体。

常用的访问控制符

访问控制符注意事项

  • public 修饰的成员可以在任意位置使用
  • private 修饰的成员只能在本类内部使用。
  • 通常情况下,成员方法都使用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 关键字导入包。
使用 import 关键字导入静态成员,从java5.0开始支持。

final基本概念

  • final本意为”最终的、不可改变的“,可以修饰类、成员方法以及成员变量。

final的使用范式

  • final关键字修饰类体现在该类不能被继承。
    • 主要用于防止滥用继承,如:java.lang.String类等。
  • final关键字修饰成员方法体现在该方法不能被重写但可以被继承。
    • 主要用于防止不经意间造成重写,如:java.text.Detaformat类中format方法等。
  • final关键字修饰成员变量体现在该变量必须初始化且不能改变。
    • 主要用于防止不经意间造成改变,如:java.lang.Tread类中MAX_PRIORITY等。

常量的概念

  • 在以后的开发中很少单独使用final关键字来修饰成员变量,通常使用 public static final 关键字共同修饰成员变量来表达常量的含义,常量的命名规范要求是所有字母都要大写,不同的单词之间采用下划线连。
  • public static final double PI = 3.14;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361