Java面向对象(下)--static/final/代码块/抽象/接口/内部类
目录
1 关键字:static
2 理解main方法的语法
3 类的成员之四:代码块
4关键字:final
5 抽象类与抽象方法
6 接口(interface)
7 类的成员之五:内部类
static
功能
含义:静态的
可以用来修饰属性、方法、代码块、内部类
使用static修饰属性:表示静态变量(类变量),没有static的为实例变量,如果创建了类的多个对象,多个对象共享同一个静态变量,当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时是修改过的
静态变量的其他说明:
- 静态变量随着类的加载而加载,早于对象的创建,和类一样只会加载一次,在内存中存在一份
- 可以通过类.静态变量的方式进行调用,而实例变量不能这样调用
- 内存解析:

- 静态方法:类似静态变量,可以通过类之间调用,随着类加载,只能调用静态的方法或属性,对于非静态方法中,既可以调用非静态方法或属性,也可以调用静态方法或属性
- 注意点:
- 静态的方法内,不能使用this关键字、super关键字
- 关于静态属性和静态方法的使用,可以从生命周期的角度理解
- 开发中,如何确定一个属性是否要声明为static?
如果属性是可以被多个对象所共享的,不会随着对象的不同而不同,如银行账户类中的利率属性
类中的常量也常常声明为static
开发中,如何确定一个属性是否要声明为static?
操作静态属性的方法,通常设置为static
工具类中的方法,习惯声明为static。比如Math、Arrays、Collections,不需要new对象即可直接用类调用方法
应用
class Circle{
private double radius;
private int id;
public Circle(){
id=init++;//可以实现每次创建自动生成连续的id
total++;
}
public Circle(double radius){
this();//先调用一次上面的构造器,不用重复
this.radius=radius;
}
private static int init=1001;
private static total;
}
单例设计模式
采取一定的方法保证整个软件系统中某个类只存在一个对象实例,且该类只提供一个取得其对象实例的方法
饿汉式
public class SingletonTest1{
public static void main(String[] args){
Bank bank1=Bank.getInstance();
Bank bank2=Bank.getInstance(); //此时bank1==bank2成立
}
}
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.内部创建类的对象,要求此对象声明为静态
private static Bank instance=new Bank();
//3.提供公共方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
懒汉式
public class SingletonTest1{
public static void main(String[] args){
Order order1=Bank.getInstance();
Order order2=Bank.getInstance(); //此时bank1==bank2成立
}
}
class Order{
//1.私有化类的构造器
private Order(){
}
//2.内部创建类的对象,要求此对象声明为静态
private static Order instance=null;
//3.提供公共方法,返回类的对象
public static Order getInstance(){
if(instance==null){
instance=new Order();
}
return instance;
}
}
区分饿汉式和懒汉式
饿汉式:对象加载时间过长(缺点),是线程安全的(优点)
懒汉式:延迟对象的创建(优点),目前的写法线程不安全,多线程内容时可以修改
使用场景
只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多资源时,可以直接产生一个单例对象,永久驻留内存
- 网站计数器,为了保证同步
- 应用程序的日志应用,因为日志文件一般一直处于打开操作,便于追加
- 数据库连接池,一个池子可以同时进行n个连接, 连接池固定一个
- 读取配置文件的类
- Application类
- windows任务管理器、回收站等
理解main方法的使用
- main()方法作为程序的入口
- main()也是一个普通的静态方法
- 可以作为我们与控制台交互的方式,之前是使用Scanner
类的成员四:代码块
相当于对属性赋值多了一种方式,实际上使用频率不高
- 代码块作用:用于初始化类、对象
- 代码块如果有修饰,只能使用static
- 分类:静态代码块 非静态代码块
- 静态代码块:
- 内部可以有输出语句
- 随着类的加载而执行;
- 用于初始化类的信息;
- 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行;
- 静态代码块的执行要优先于非静态代码块的执行
- 非静态代码块:
- 内部可以有输出语句
- 随着对象的创建(new)而执行
- 每创建一个对象就执行一次
- 作用是可以在创建对象时,对对象的属性等进行初始化
- 如果一个类中定义了多个非静态代码块,则按照声明先后顺序执行
- 属性赋值的执行顺序
默认初始化--显式初始化/代码块中赋值--构造器中初始化--对象.属性或对象.方法赋值
final关键字
- final可以修饰的结构:类、方法、变量
- final类:此类不能被其他类继承,如String、System、StringBuffer
- final方法:不允许被重写,比如Object中getClass
- final变量:此时的变量称为是一个常量,不允许改变
- 允许的赋值位置有:显示初始化,代码块中初始化、构造器中初始化
- final局部变量:尤其是使用final修饰形参时,表明此形参是常量,调用此方法时给该形参赋值,之后方法中只能使用不能重新赋值
- static final修饰属性:全局常量,接口中属性全是全局常量
- 用途:一般方法不常使用,属性有时需要final
抽象类与抽象方法
abstract意为抽象的,用来修饰结构、类、方法
抽象类
abstract修饰类:抽象类,此类不能实例化
- 抽象类中一定有构造器,便于子类实例化时调用
- 一般开发中都会提供子类
抽象方法
- 只有方法的声明,没有方法体
- 包含抽象方法的类必须是抽象类,但抽象类中可以没有抽象方法
- 若子类重写了父类所有抽象方法后,子类方可实例化
abstract class Person{
public abstract void eat();
}
使用上的注意点
- abstract不能用来修饰属性、构造器等结构
- 不能用来修饰私有方法、静态方法、final方法
创建抽象类的匿名子类
//Person定义为抽象类,Worker/Student为Person的子类
Worker worker=new Worker();
method(worker);//非匿名类非匿名对象
method(new Student()); //非匿名类匿名对象
//创建了一各匿名子类的非匿名对象:p
Person p=new Person(){
@override
public void eat(){//抽象类的子类必须重写其中的抽象方法
}
}
//创建匿名子类的匿名对象
method(new Person(){
@override
public void eat(){//抽象类的子类必须重写其中的抽象方法
}
})
模板方法设计模式
public class TemplateTest{
SubTemplate t=new SubTemplate();
t.spendTime();
}
abstract class Template{
//计算某段代码执行花费的时间
public void spendTime(){
long start=System.currentTimeMillis();
code();//不确定的,易变的部分
long end=System.currentTimeMillis();
System.out.println("花费的时间为"+(end-start));
}
public abstract void code();
}
class SubTemplate extends Template{
@override
public void code(){
System.out.println("sss");
})
}
}
接口
- 有时需要从几个类派生出一个子类,java不支持多重继承,类无法满足这个条件。
- 有时需要从几个类提取共同行为特征,但又没有is-a关系,只是有相同的行为特征。如大学生中学生都是学生,跨栏运动员篮球运动员都是运动员,他们都具有学习的技能,一方面他们已经有父类,另一方面他们与技能不满足子父类关系,因此可以把技能定义为接口
接口的使用
接口使用interface来定义
java中,接口和类是并列的两个结构
如何定义接口:定义接口中的成员
3.1 JDK7及以前:接口中只能定义全局常量和抽象方法
全局常量:
public static final(即使省略这几个词依然是全局常量)抽象方法:
public abstract(即使省略这几个词依然是抽象方法)接口中不能定义构造器!!意味着接口不可以实例化
3.2 JDK8以后 除了全局常量和抽象方法还可以定义静态方法和默认方法
Java开发中,接口通过让类去实现(Implements)的方法来使用
如果实现类重写了接口中所有抽象方法,则此实现类可以实例化
如果没有覆盖所有抽象方法,则此实现类仍为抽象类
java类可以实现多个接口,打破了类的单继承性的局限性,多个接口用
implements A,B即可接口与接口间可以继承,且可以多继承
接口的具体使用体现的多态性,接口实际上可以看做一种规范
package com.atguigu.ex1;
public class test {
}
interface Flyable{
public static final int MAX_SPEED=7900;
int MIN_SPEED=7900;
public abstract void fly();
void stop();
}
//重写全部抽象方法 可以实例化
class plane implements Flyable{
@Override
public void fly() {
System.out.println("起飞");
}
@Override
public void stop() {
System.out.println("停止");
}
}
//未重写全部抽象方法 必须为抽象类
abstract class Kite implements Flyable{
@Override
public void fly() {
// TODO Auto-generated method stub
}
}
//接口间多继承
interface AA{
}
interface BB{
}
interface CC extends AA,BB{
}
代理模式
应用场景:
安全代理:屏蔽对真实角色的直接访问
远程代理:通过代理类处理远程方法调用
延迟加载:先加载轻量级代理对象,需要再加载真实对象
分类:
静态代理
动态代理
工厂设计模式
实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽起来,达到提高灵活性的目的
简单工厂模式,定义一个实现类对象的工厂类XXXFactory,包含getXXX等功能但是增加产品时需要对现有代码进行修改,违反了开闭原则
工厂方法模式,定义一个工厂接口,N个工厂类实现工厂接口,即可
Java8接口新特性
除了定义全局常量和抽象方法以外,还可以定义静态方法、默认方法
静态方法
1.接口中定义的静态方法,只能通过接口调用
2.通过实现类的对象,可以调用接口中的默认方法
3.如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,那么子类没重写时,默认调用父类该方法(类优先原则)
但属性不允许重名
4.如果实现类实现了多个接口,而多个接口中定义了同名同参数默认方法,那么实现类没有重写此方法时报错(接口冲突),这就需要在实现类中重写此方法
public class SubclassTest {
public static void main(String[] args) {
Subclass s=new Subclass();
//s.method1(); 接口的实现类调用会报错
//1.接口中定义的静态方法,只能通过接口调用
CompareA.method1();
//2.通过实现类的对象,可以调用接口中的默认方法
s.method2();
s.method3();
}
}
package com.atguigu.ex1;
public interface CompareA{
public static void method1() {
System.out.println("method1");
}
public default void method2() {
System.out.println("method1");
}
default void method3() {
System.out.println("method1");
}
}
内部类
一个类定义于另一个类的内部,称为内部类,反之为外部类
- 内部类一般用在定义它的类或语句块内,外部引用时必须给出完整的名称
- 内部类分类:成员内部类(静态、非静态) 局部内部类(方法内、代码块内、构造器内)
- 成员内部类:可以调用外部类的结构;可以定义属性、方法、构造器等;可以被final、abstract修饰
关注三个问题:
- 如何实例化成员内部类的对象
//创建Brain实例 静态的成员内部类
Person.Brain br=new Person.Brain();
//创建Eye实例 非静态的成员内部类
Person person=new Person();
Person.Eye eye=person.new Eye();
- 如何在成员内部类中区分调用外部类的结构
如果Person有内部类Brain,都定义了name属性,且Brain中有个方法形参为name,则
name 形参
this.name Brain类中的
Person.name Person中的
- 开发中局部内部类的使用
面试题:抽象类与接口异同
相同点:
- 不能实例化
- 都可以被继承
不同点:
- 抽象类有构造器,接口不能声明构造器
- 抽象类只能单继承,接口可以多继承
Java面向对象(下)--static/final/代码块/抽象/接口/内部类的更多相关文章
- Java 面向对象之static,final,匿名对象,内部类,包,修饰符
01final关键字概念 A: 概述 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承, 或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这 ...
- Java面向对象(static、final、匿名对象、内部类、包、修饰符、代码块)
面向对象 今日内容介绍 u final u static u 匿名对象 u 内部类 u 包的声明与访问 u 四种访问修饰符 u 代码块 第1章 final关键字 1.1 final的概念 继承的出现提 ...
- java基础课程笔记 static 主函数 静态工具类 classpath java文档注释 静态代码块 对象初始化过程 设计模式 继承 子父类中的函数 继承中的构造函数 对象转型 多态 封装 抽象类 final 接口 包 jar包
Static那些事儿 Static关键字 被static修饰的变量成为静态变量(类变量) 作用:是一个修饰符,用于修饰成员(成员变量,成员方法) 1.被static修饰后的成员变量只有一份 2.当成员 ...
- 2017.10.23 Java 面向对象深入学习---final 关键字、static关键字、匿名对象等
今日内容介绍 1.final 关键字 2.static 关键字 3.匿名对象 4.内部类 5.包的声明与访问 6.访问修饰符 7.代码块 第一节课 01(面向对象)final关键字概念.avi 02: ...
- java 中的静态(static)代码块
类字面常量 final 静态域不会触发类的初始化操作 非 final static 静态域(以及构造器其实是一种隐式的静态方法) Class.forName():会自动的初始化: 使用 .class来 ...
- Java之static静态代码块
Java之static静态代码块 构造代码块 使用{}包裹的代码区域,这里的代码区域特指位于class{}下面的而不是存在于其他type method(){}这类函数下面的代码区域 public cl ...
- Java static 静态代码块、代码块
简述 static{} 静态代码块,加载类之前执行 {} 代码块,每次new的时候都会被执行 示例 类: public class Student { int age; String name; bo ...
- java里的static/final含义
java里的static/final含义 static static可以修饰:属性,方法,代码段,内部类(静态内部类或嵌套内部类) static修饰的属性的初始化在编译期(类加载的时候),初始化后能改 ...
- static{}静态代码块与{}普通代码块之间的区别
先看一个例子: //class A package com.my.test; class A { static { System.out.println("A1:父类静态代码区域" ...
- Java面向对象12——static详解
static package oop.demon01.demon07; // static : public class Student { private static int a ...
随机推荐
- TienChin 渠道管理-工程创建
因为本文章主要围绕着项目开发进行,所以前言不做开头,直接上内容. 添加字段 我们的渠道表,我看到若依脚手架当中有一个是否删除的标志字段,所以我这里也添加一下: ALTER TABLE `tienchi ...
- springboot整合nacos的入门Demo
Nacos介绍 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现.配置管理和服务 ...
- 2.3 Windows驱动开发:内核字符串转换方法
在内核编程中字符串有两种格式ANSI_STRING与UNICODE_STRING,这两种格式是微软推出的安全版本的字符串结构体,也是微软推荐使用的格式,通常情况下ANSI_STRING代表的类型是ch ...
- C/C++ 搜索缝隙并插入ShellCode
将ShellCode放入变量中,然后修改插入可执行文件名称,运行后即可将shellCode插入到EXE中,并设置好装载地址,程序运行后会先上线,然后在执行原始的代码,在使用metaspoit生成she ...
- ASP.NET Core 6.0+Vue.js 3 实战开发(视频)
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章或视频能成为你成长路上的垫脚石. 录制视频的体验 这是一个收费的视频,很抱歉,让您失望了. 我尝试做点收费的视频,不是因为我不 ...
- 教你用JavaScript实现搜索展开
欢迎来的我的小院,恭喜你今天又要涨知识了! 案例内容 利用JavaScript实现搜索框的移动展开. 演示 学习 <!DOCTYPE html> <html lang="e ...
- 记录一则ADG备库报错ORA-29771的案例
有客户找到我这边咨询,说他们的一套核心ADG库在业务高峰期报错,因为业务做了读写分离,其备库也实际承担读业务,所以备库故障也会对业务产生影响. 这里也要提醒大家,做读写分离,如果读库出现故障的情况,要 ...
- 尴尬:在zoom中找不到会议密码
临时要开一个zoom会议,点击"新会议"进入,然后邀请其他与会者. "会议" - "复制邀请链接", 得到一行这样的信息(会议号已模糊处理) ...
- 《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(中)
第 3 章 ASP.NET Core 核心特性 3.3 依赖注入 通常情况下,应用程序由多个组件构成,而组件与组件之间往往存在依赖关系 当我们需要获取数据时,通常的做法是实例化依赖的类,然后调用类里面 ...
- MySQL8.0-CTE递归查询(避免死循环)
TSQL脚本能实现递归查询,用户使用共用表表达式 CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询. 本文详细介绍CTE递归调用的特性和使用示例,递归查 ...