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 ...
随机推荐
- SqlSugar的查询函数SqlFunc
用法 我们可以使用SqlFunc这个类调用Sql函数,用法如下: db.Queryable<Student>().Where(it => SqlFunc.ToLower(it.Nam ...
- 强化学习调参技巧一: DDPG算法训练动作选择边界值_分析解决
1.原因: 选择动作值只在-1 1之间取值 actor网络输出用tanh,将动作规范在[-1,1],然后线性变换到具体的动作范围.其次,tanh激活区是有范围的,你的预激活变量(输入tanh的)范围太 ...
- jetbrains 系列 terminal history 设置
之前的版本中 jetbrains 的 terminal 使用的是 ~/.zsh_history, 改版后使用的不是一个 history, 就会出现在 iterm2 中使用的 command, 在 py ...
- 在IntelliJ IDEA中,开发一个摸鱼看书插件
作者:小傅哥 博客:https://bugstack.cn 原文:https://mp.weixin.qq.com/s/R8qvoSNyedVM95Ty8sbhgg 沉淀.分享.成长,让自己和他人都能 ...
- 设计模式(三十二)----综合应用-自定义Spring框架-自定义Spring IOC-自定义Spring IOC总结
1 自定义Spring IOC总结 1.1 使用到的设计模式 工厂模式.这个使用工厂模式 + 配置文件的方式. 单例模式.Spring IOC管理的bean对象都是单例的,此处的单例不是通过构造器进行 ...
- Java开发学习(二十)----AOP总结
一.AOP的核心概念 概念:AOP(Aspect Oriented Programming)面向切面编程,一种编程范式 作用:在不惊动原始设计的基础上为方法进行功能增强 核心概念 代理(Proxy): ...
- python高级用法之命名元组namedtuple
1.tuple类型数据的获取 大家都知道,元组里面的数据获取只能通过下标的方式去获取,比如 :a = ('username', 'age', 'phone'),要获取username的话 ,就需要用a ...
- 如何用低代码实现批量导出PDF?
前言 事情是这样的,熟悉我们的朋友都知道,我司有一个为广大开发者朋友们提供学习帮助的地方,叫做新手训练营,具体的内容就是会针对初次接触葡萄城产品和技术的用户,通过 2-3 天的集中学习,采用直播授课的 ...
- IIS配置跨域
在IIS里找到HTTP响应标头 添加如下两个标头 Access-Control-Allow-Headers:Content-Type, api_key, Authorization Access-Co ...
- 【分布式】load balance 02-consistent hash algorithm 一致性哈希算法原理详解
负载均衡系列专题 01-负载均衡基础知识 02-一致性 hash 原理 03-一致性哈希算法 java 实现 04-负载均衡算法 java 实现 概念 一致哈希是一种特殊的哈希算法. 在使用一致哈希算 ...