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 ...
随机推荐
- 获取Visual Studio所用MSVC编译器版本:_MSC_VER数值
本文介绍查看Visual Studio软件_MSC_VER值的方法. _MSC_VER是微软公司推出的C/C++编译器--MSVC编译器的一个内置宏,其值表示当前Visual Studio软件 ...
- ElasticSearch安装、插件介绍及Kibana的安装与使用详解
ElasticSearch安装.插件介绍及Kibana的安装与使用详解 1.安装 ElasticSearch 1.1 安装 JDK 环境 因为 ElasticSearch 是用 Java 语言编写的, ...
- 总结一个问题:csdn发布文章页面为空或者创作内容管理为空
总结一个问题:csdn发布文章页面或者创作内容管理为空 解决方案: 打开chrome浏览器的设置: 点击清除数据: 选择高级里清除数据,一般24小时就可以了,不行就7天
- gym.spaces中找不到prng解决方案
gym.spaces中找不到prng解决方案 在运行飞桨MADDPG问题是遇到模型无法导入不存的的问题: ModuleNotFoundError: No module named 'multiagen ...
- 计算机网络|思维导图|自顶向下方法|MindMaps资料分享
前言 那么这里博主先安利一下一些干货满满的专栏啦! 手撕数据结构https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014. ...
- DoraCloud桌面模板制作教程
模板制作是桌面云部署时的一项重要工作.模板的质量直接影响到虚拟桌面业务运行的稳定性.安全性和用户体验.制作模板需要完成如下一些工作: 安装Windows桌面操作系统. 安装虚拟化平台相关的半虚拟化驱动 ...
- liveness-probe探针和readness-probe
目录 探针 liveness-probe 存活探针 探针的3种方式 1. exec 2. httpGet 3. tcpSocket readness-probe 就绪探针 1. exec 2. htt ...
- Linux-find命令报错: missing argument to `-exec'
报错提示:find: missing argument to `-exec' 今天写一个清理脚本,用到了find命令.本来是这么写的: find . -type f -mtime +7 -name & ...
- react中的setState是同步还是异步?react为什么要将其设计成异步?
壹 ❀ 引 了解react的同学都知道,react遵守渲染公式UI=Render(state),状态决定了组件UI最终渲染的样子(props也可以理解为外部传入的状态),由此可见state对于reac ...
- NC20812 绿魔法师
题目链接 题目 题目描述 "我不知道你在说什么,因为我只是个pupil."--绿魔法师 一个空的可重集合S. n次操作,每次操作给出x,k,p,执行以下操作: 1.在S中加入x. ...