package com.bawei.multithread;
//注意:模板方法我们通常使用抽象类或者抽象方法!这里我们为了方便在本类中使用就没有使用抽象类/抽象方法
public class TemplateThread {
//如果这个方法不想被子类或者别人随意改动[这样子类就不能覆写该方法了],这里方法就要设置为final方法
public final void println(String message){
System.out.println("#######################");
wrapPrint(message);
System.out.println("#######################");
}
//这个方法只允许被子类或者自身所覆盖,所以这里我们用protected关键字!
protected void wrapPrint(String message){ } public static void main(String[] args) {
//这里用TemplateThread类的匿名子类创建了一个对象,并覆盖了这个TemplateThread类的wrapPrint()方法!
TemplateThread t1 = new TemplateThread(){
@Override
protected void wrapPrint(String message) {
// TODO Auto-generated method stub
System.out.println("*"+message+"*");
}
};
t1.println("哈哈"); //这里实际上是TemplateThread类的匿名子类创建了一个匿名对象,然后调用这个匿名对象的println()方法!只不过在这里
//用匿名子类的时候,覆盖了父类中的wrapPrint方法,同时需要提醒大家的是,如果父类【TemplateThread】中的方法如果
//是抽象方法的话,那么子类就必须实现这个抽象方法,而如果父类中的这个方法只是一个空方法体的话,子类可以选择覆盖,也可以
//选择不覆盖!!
new TemplateThread(){
@Override
protected void wrapPrint(String message) {
// TODO Auto-generated method stub
System.out.println("======="+message+"=====");
}
}.println("哈哈");
}
}

  我想我们上面的这段代码已经很好的阐释了我们的标题要讲的知识点,这里要好好体悟,再一个就是:这个通过匿名类创建的匿名对象,然后调用这个匿名对象的println()方法实际上是仿照我们的Thead线程类的start()方法实现的,也就是说:我们多线程Thread类的start()方法的源码中大家可以看到实际上是调用了start0()方法,而这个方法是native修饰的,也就是由C++写的,在这个方法内部实际上又调用了我们Thread类的run()方法,这就很像我们在上面代码中父类TemplateThread中的println()方法中调用了wrapPrint()方法,而这里的wrapPrint()方法只是一个空实现,也就是说子类可以实现也可以不实现,实际上是和我们调用Thead创建子类的时候是一致的,我们可以覆盖这个Thead类的run()方法,yekeyi 不覆盖,这是因为Thead/类本身已经为我们实现了这个run()方法,如果必须要子类覆盖或者实现的话,可以将这个方法设置为抽象方法!也就在TemplateThread中我们可以将wrapPrint设置为抽象方法,那么TemplateThread的子类就必须实现这个方法了,然后子类的对象也就可以直接调用println()方法了!就javaapi给我们提供的这个Thread类而言,我们是可以覆写它的start()方法的,因为这个方法不是final类型的,但是如果我们覆写了start()方法,那么它就不会有源码中的start0()方法来调用c++的程序了!所以我们这个说明了,为什么我命名调用的是run()方法而我们在运行程序的时候却是调用的是start()方法呢?原因就是Thead类这里用的是模板方法的一个技巧,就是和上面我们自己写的代码类似,在一个方法1中调用另一个方法2,我们需要覆写的是方法2,但是我们运行代码的时候调用的却是方法1,因为方法1为我们调用了方法2,而且在调用方法2的前后还做了其它工作!

2.匿名类,匿名类对象,private/protected/public关键字、abstract抽象类,抽象方法、final关键字的使用,多线程Thread类start方法原理的更多相关文章

  1. private,protected,public和default的区别

    private,protected,public和default的区别 除了default以外,其他都是Java语言的关键字.default代表的是对类成员没有进行修饰的情况.它本身也代表了一种访问控 ...

  2. @private@protected@public@package

    @private@protected@public@package 为了强制一个对象隐藏其数据,编译器限制实例变量范围以限制其在程序中的可见性 但是为了提供灵活性,苹果也让开发者显式设置范围(四选一) ...

  3. 探Java多线程Thread类和Runnable接口之间的联系

    首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说  有如下两种情 ...

  4. 【Java】abstract,final,static,private,protected,public的区别

    [abstract]抽象的 1. abstract可以修饰类和成员方法,被abstract修饰的类称为抽象类,被abstract修饰成员方法叫抽象方法.抽象类不一定有抽象方法,但拥有抽象方法的类一定是 ...

  5. 对private protected public的详解:

    #include <iostream> #include <stack> #include <queue> #include <exception> # ...

  6. java: private, protected, public

    这三个 「可访问修饰符」,是一个老生常谈的话题了.在 C++ 中也有类似的概念. 按其修饰对象的不同,分为几种用法小记一下: 用于类 只有 public 可以修饰类:private 和 protect ...

  7. oc 中四种实例变量的范围类型@private@protected@public@package

    To enforce the ability of an object to hide its data, the compiler limits the scope of instance vari ...

  8. iOS中四种实例变量的范围类型@private@protected@public@package

    文档上记录是这样的 The Scope of Instance Variables Toenforce the ability of an object to hide its data, the c ...

  9. 多线程----Thread类,Runnable接口,线程池,Callable接口,线程安全

    1概念 1.1进程 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 任务管理器中: 1.2线程 线程是进程中的一个执行单元 ...

随机推荐

  1. day3_元组

    元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 一.创建元组 1.普通创建 实例1: >> ...

  2. Linux 下安装JDK和jmeter 及环境配置记录过程

    一.安装首先要查看linux系统的位数,用命令getconf LONG_BIT,我的是centOS 32位 二.官网下载32位的JDK8 http://www.oracle.com/technetwo ...

  3. MySQL Community Server 8.0.11下载与安装配置

    一.下载 1.选择合适的安装包,我在这里下载的是目前最新的安装包,8.0.11,而且我选择下载的是解压版的,安装版的话,安装会比较麻烦. MySQL Community Server下载链接:http ...

  4. Docker 容器(六)

    镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体.容器可以被创建.启动.停止.删除.暂停等. 容器的实质是 ...

  5. Linux ifconfig 命令

    在centos6 自带ifconfig 在centos7 默认不带ifconfig,需要自己安装 ifconfig命令用来配置或查看网卡接口,常见用法如下: 安装ifconfig命令 [root@my ...

  6. 清空select标签中option选项的3种不同方式

    方法一 代码如下:document.getElementById("selectid").options.length = 0; 方法二 代码如下:document.formNam ...

  7. Pro*C介绍

    内嵌SQL 概要 Pro*C语法 SQL 预处理指令 语句标号 宿主变量 基础 指针 结构 数组 指示器变量 数据类型同等化 动态SQL 事务 错误处理 SQLCA WHENEVER语句 Demo程序 ...

  8. 单例模式多线程安全写法(double-lock-check)

    原始版本 public static Object getInstance() { if (instance != null) { return instance; } instance = new ...

  9. Laravel中路由怎么写(二)

    1.路由命名——给路由起个名字 1.1 基本使用 我们使用as关键字来为路由命名: Route::get('/hello/Laravel',['as'=>'academy',function() ...

  10. 15-Python3 编程第一步

    2018-11-20 11:42:06 ''' 肥婆纳妾数列 斐波那契数列,又称黄金分割数列:这个数列从第3项开始,每一项都等于前两项之和, 随着数列项数的增加,前一项与后一项之比越来越逼近黄金分割的 ...