JAVASE的学习笔记(四)(抽象类,代码块,接口)
JAVASE的学习笔记(四)
抽象类与接口
- JAVASE的学习笔记(四)
- 代码块
- 例题:
- 静态代码块
- 加载类的方法
- 手动加载类
- 抽象类(**只能被继承使用,自己应该无法创建对象**)
- 重要:
- 抽象类由abstract修饰,由abstract修饰的方法为抽象方法
- abstract修饰符
- `模版设计模式`**(请计算代码的运行时间)
- 正常方法:
- 接口环境
- 定义
- 作用
- 特点1:接口的定义必须使用`interface`来定义
- 特点2:接口是特殊的抽象类,只是包含公共的抽象方法和公共的静态常量(JDK8之后可以包含默认方法和静态方法定义)
- 特点3:接口中不存在构造方法,因此无法进行实例化操作
- 特点4:接口必须由`实现类`进行`实现方法`操作(接口的主要作用)
- 特点5:一个实现类可以实现多个接口,使用`implements`关键字
- 特点6:一个接口可以继承多个接口(目的:解决单一继承问题)
- 特点7:如果一个类出现了继承和实现,那么必须是先`extends`后`implements`
- 特点8:接口的另一个作用:解耦
- 接口与抽象类的差异
- 开发模式:接口代理模式
代码块
java中首先是静态块先执行,静态方法,然后初始化代码块,最后是构造函数
- 普通代码块:是在方法内部中使用(普通代码块中定义的变量是局部变量作用范围只能在代码块的范围,并且名称不能和局部变量重复)
注意:执行子类的构造方法,先执行父类的构造方法,初始化代码优于构造方法之前执行,构造方法和初始化代码块在new对象的时候执行,而静态语句块和静态方法在类加载到内存的时候就已经执行了。 - 初始化代码块:基本不使用,在创建对象的时候,我们会对成员变量进行初始化操作,是针对成员变量赋值使用(每次创建对象,初始化代码都是优于构造方法之前执行)
- 静态代码块:静态代码块:随着类的加载而加载,static进行修饰,存储在数据全局区域,只能执行一次
- 同步代码块:常用(多线线程使用)
Class.forName():返回与给定的字符串名称相关联类或接口的Class对象。是一个静态方法,相同能够用来载入类。
例题:
/*
预测答案:
*/
public class Demo4{public static void main(String...args)throws Exception{// Class.forName("C");C c = new C("悟空",100,"男生",999);System.out.println(c);}
}
class A{{System.out.println("A类的初始化代码块");}static{System.out.println("A类的静态代码块");}public A(){System.out.println("A类的构造方法");}
}
class B extends A{private String name;private int age;{System.out.println("B类的初始化代码块");}static{System.out.println("B类的静态代码块");}public B(){System.out.println("B类中的无参数的构造方法");}public B(String name,int age){//隐含super(),所以先执行父类构造方法System.out.println("B类中的有.....参数的构造方法");}
}
class C extends B{private String sex;private int money;{System.out.println("C类的初始化代码块");}static{System.out.println("C类的静态代码块");}public C(String name,int age,String sex,int money){super(name,age);//若没有此行代码,那就执行B类中午餐this.sex = sex;this.money = money;}
}
运行结果:
静态代码块
加载类的方法
- 由 new 关键字创建一个类的实例(静态加载)
在由运行时刻用 new 方法载入
如:Student student = new Student(); - 调用 Class.forName() 方法(动态加载)
通过反射加载类型,并创建对象实例
如:Class clazz = Class.forName(“Student ”);
Object student =clazz.newInstance(); - 调用某个 ClassLoader 实例的 loadClass() 方法
通过该 ClassLoader 实例的 loadClass() 方法载入。应用程序可以通过继承 ClassLoader 实现自己的类装载器。
如:Class clazz = classLoader.loadClass(“Student ”);
Object student =clazz.newInstance();
区别:
- 1和2使用的类加载器是相同的,都是当前类加载器。(即:this.getClass.getClassLoader)。3由用户指定类加载器。如果需要在当前类路径以外寻找类,则只能采用第3种方式。第3种方式加载的类与当前类分属不同的命名空间。
- 1是静态加载,2、3是动态加载
异常:
静态加载的时候如果在运行环境中找不到要初始化的类,抛出的是NoClassDefFoundError,它在JAVA的异常体系中是一个Error
动态态加载的时候如果在运行环境中找不到要初始化的类,抛出的是ClassNotFoundException,它在JAVA的异常体系中是一个checked异常
手动加载类
package com.os.test;public class C_静态代码块 {public static void main(String[] args)throws Exception {//类是对象的“蓝图(模版)”=>模版也是对象=>个性对象//随着类的加载而加载,加载类到“方法区”(类的信息、全局数据区域static、常量池)//Class clazz1 = Person.class;//不会执行静态代码块//System.out.println(clazz1);//创建对象的时候才开始加载//Person p1 = (Person)clazz1.newInstance();//System.out.println("p1 = " + p1);//Person p2 = new Person();//先加载类的信息,才能创建对象,会执行静态代码块/** 上述两种方式,我们使用的类必须存在,如果不存在,编译无法通过* *///手动加载类//Class.forName("com.osasdfasdf.asdfsadf.asdf.sadf");//编译通过,该类在运行的时候才报错ClassNotFoundExceptionClass.forName("com.os.test.Person");//加载静态代码块}
}
class Person{static{System.out.println("静态代码块:随着类的加载而加载");}public Person(){System.out.println("Person的构造方法");}
}
静态代码块随着类的加载而加载,加载类到“方法区”(类的信息、全局数据区域static、常量池),所以;
Class clazz1 = Person.class=>不会执行静态代码块,这行代码只是获取了类对象,并没有加载类
Person p2 = new Person()=>可以执行静态代码块,因为代码创建了对象
手动加载:
Class.forName(“com.os.test.Person”)=>没有创建对象却加载静态代码块
主要功能
Class.forName()返回的是一个类。
Class.forName()的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。
抽象类(只能被继承使用,自己应该无法创建对象)
重要:
1. getClass():返回此 Object 的运行时类
2. getName():以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
3. 显示实际堆内存中对象
抽象类由abstract修饰,由abstract修饰的方法为抽象方法
- 有抽象方法的类,必然是抽象类-抽象类中可以没有抽象方法,,
个人认为:你设计了抽象类,没有抽象方法,那么该类就没有“意义”
有道面试题说抽象类中必须得有抽象方法,答案是错误。 - 抽象类中可以存在构造方法,但是无法进行实例化(不能创建对象)
- 重要作用:抽象类除了被继承外,没有作用
- 继承使用之后,有两种情况:
- 子类必须重写父类中的抽象方法
- 子类如果没有重写父类中的抽象方法,那么该子类一定为抽象类
- 抽象方法不能被
final
,static
,private
修饰 - 抽象类必须使用
abstract
进行修饰,但是不能使用final
,static
修饰abstract
1.final关键字:final修饰类不能被继承,final修饰方法不能被重写,final修饰变量不能改变值。而abstract修饰类必须被继承,两者同时出现非法组合。
abstract修饰符
- 修饰的类即为抽象类,不能被实例化
- 构造方法和static不能是抽象的
- 父类的抽象方法往往在子类中实现,抽象类可以具有指向子类对象的对象引用
public class Demo01{public static void main(String...args){交通工具 m = new 汽车();System.out.println(m.getClass().getName());}
}
abstract class 交通工具{//如果一个类中存在抽象方法,那么该类一定是为抽象类public abstract void run();//定义成抽象方法public 交通工具(){System.out.println("交通工具...构造方法");}
}
class 汽车 extends 交通工具 {//子类不是抽象类,那么必须要重写父类的抽象方法汽车(){System.out.println("汽车....构造方法");}public void run(){System.out.println("汽车。。重写抽象方法");}
}
abstract class 火车 extends 交通工具 {//子类没有重写父类中的抽象方法,该子类一定为抽象类火车(){System.out.println("火车....构造方法");}
}
模版设计模式
**(请计算代码的运行时间)
class test01{public static void main(String[] args){Template p1 = new M1();System.out.println(p1.getRuntime());}
}
abstract class Template {public long getRuntime(){long start = System.currentTimeMillis();this.code();long end = System.currentTimeMillis();return end-start;}public abstract void code();//抽象方法
}
class M1 extends Template {public void code() {double sum = 0;for (int i=0;i<100000;i++){sum+=Math.random();}}
}
正常方法:
class 复习06 {public static void main(String[] args){long start = System.currentTimeMillis();//返回当前时间的时间戳int sum = 0;for (int i=0;i<100000;i++){sum+=i;}long end = System.currentTimeMillis();System.out.println((end-start)+"ms");}
}
接口环境
定义
可以理解接口是一种“极特殊”的== 抽象类==,使用interface定义接口, 接口中只能包含公共的抽象方法和公共的静态常量(JDK8以后的版本,接口可以包含普通方法)
接口没有构造方法
作用
- 以后的开发都会面向接口编程(是对面向对象编程的补充)
- public interface Demo01{//1.使用interface关键字定义接口/*个人不推荐:在接口中给定义常量*/public static final String NAME = "悟空";/*public static final */String BOOK_NAME = "西游记";/*A.方法都为公共的抽象方法*/public abstract int m1();/*public abstract*/ int m2();//个人推荐public /*abstract*/ int m3();//=================JDK8以后=========================// static修饰符定义静态方法static void staticMethod() {System.out.println("接口中的静态方法");}// default修饰符定义默认方法default void defaultMethod() {System.out.println("接口中的默认方法");}}
特点1:接口的定义必须使用interface
来定义
特点2:接口是特殊的抽象类,只是包含公共的抽象方法和公共的静态常量(JDK8之后可以包含默认方法和静态方法定义)
特点3:接口中不存在构造方法,因此无法进行实例化操作
特点4:接口必须由实现类
进行实现方法
操作(接口的主要作用)
- 实现类必须实现接口中所有的抽象方法
- 实现类没有实现接口中的抽象方法,那么该实现类一定为抽象方法
特点5:一个实现类可以实现多个接口,使用implements
关键字
特点6:一个接口可以继承多个接口(目的:解决单一继承问题)
特点7:如果一个类出现了继承和实现,那么必须是先extends
后implements
特点8:接口的另一个作用:解耦
接口声明变量引用对应实现类的地址<=等价说法=>接口声明实现类进行实例化
接口与抽象类的差异
- 接口提供了一种多重继承的形式,而类只能扩展一个其它的类(包括抽象类)
- 抽象类中可以有普通方法(包括protected,static方法)和普通变量的声明,但接口中只能有public的常量和抽象方法
开发模式:接口代理模式
电影制片厂,需要制作一部电影,某个导演完成了一部《异界》,需要在影院在播放期间需要对该影片进行宣传
interface 电影工厂{void film();
}
class 异界 implements 电影工厂{public void film(){System.out.println("异界经过了很多的艰苦过程");}
}
class 影院 implements 电影工厂{private 电影工厂 proxy ;public 影院(电影工厂 obj){this.proxy = obj;}public void film(){before();//增加功能proxy.film();//没有改变原来核心代码after();//增加功能}private void before(){System.out.println("播放前的宣传");}private void after(){System.out.println("播放后的口碑");}
}
public class Demo03{public static void main(String...args){异界 target = new 异界();//接口回调影院 aa = new 影院(target);//电影工厂 obj = target = new 异界()aa.film();}
}
JAVASE的学习笔记(四)(抽象类,代码块,接口)相关推荐
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- xilinx 暑期学校学习笔记(四) 加速代码与量化、稀疏
文章目录 矩阵乘法的优化 矩阵的reshape 缓存的加入 PIPELINE REWIND 卷积神经网络加速 分块划分 访问和内存的流水化 卷积层量化和稀疏 模型量化 带宽 稀疏化 存储 脉动阵列 实 ...
- Gentle.Net学习笔记四:修改代码,使用Oracle数据库
开始使用Gentle.Net的时候,我使用编译好的类库,可是不久就发现,如果要更好的利用Gentle.Net,你就不得不做一些修改,所以,还是使用源代码的方式为好. 使用源代码,Gentle.N ...
- 吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码
吴恩达<机器学习>学习笔记四--单变量线性回归(梯度下降法)代码 一.问题介绍 二.解决过程及代码讲解 三.函数解释 1. pandas.read_csv()函数 2. DataFrame ...
- JavaScript学习笔记(四)(DOM)
JavaScript学习笔记(四) DOM 一.DOM概述 二.元素对象 2.1 获取方式 (1).通过ID获取一个元素对象,如果没有返回null (2).通过`标签名`获取一组元素对象,,如果没有返 ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- JSP学习笔记(四十九):抛弃POI,使用iText生成Word文档
POI操作excel的确很优秀,操作word的功能却不敢令人恭维.我们可以利用iText生成rtf文档,扩展名使用doc即可. 使用iText生成rtf,除了iText的包外,还需要额外的一个支持rt ...
- oracle protocol=beq 不可用,学习笔记:Oracle数据库坏块 深入研究obj$坏块导致exp/expdp不能执行原因...
天萃荷净 深入研究Oracle坏块obj$导致exp/expdp不能执行导出的原因 上篇(案例:Oracle出现obj$坏块exp/expdp导出不能导出的解决办法ORA-01578 ORA-0111 ...
- esp8266舵机驱动_arduino开发ESP8266学习笔记四—–舵机
arduino开发ESP8266学习笔记四-–舵机 使用时发现会有ESP8266掉电的情况,应该是板上的稳压芯片的限流导致的,观测波形,发现当舵机运转时,电源线3.3V不再是稳定的3.3V,大概是在3 ...
最新文章
- 第一课.python入门与环境介绍
- rhel5.1 vncserver
- java----java工具包
- 经典C语言程序100例之十七
- Keras深度学习框架介绍(结束)
- 关于新的描述语言GEZEL的介绍
- CDH集群安装配置(五)- Cloudera Manager Server
- 七桥问题c语言程序数据结构,数据结构与算法学习——图论
- 阿里云主机(aliyun-Linux) x64安装Redis详解
- FastReport的动态页面设置
- 齐次坐标和单应性矩阵
- 5-5 多边形周长计算(继承)
- 锅打灰太狼/打地鼠项目
- 如何快速掌握一门技术
- 怎么获取自定义核算项目里某一个类型的数据:做f7
- 网站文章采集与伪原创技巧
- 移动端字体加粗的解决方案
- 中国光学镜头行业营销趋势及盈利前景预测报告(新版)2022-2027年
- 页面刷新指定到原先滚动条位置
- 怎样设置word背景图片每一页都不同