代码重复性高,函数用于封装代码,把一个函数的代码变成由多个函数组成
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的方法,那么这时就将不确定的部分暴露出去。由该类的子类去完成
eg:
abstract class GetTime{
public final void getTime(){//为了防止覆写
long start = System.currentTimeMillis();
runcode();
long end = System.currentTimeMillis();
System.out.println("毫秒:"+(end-start));
}
class SubTime extends GetTime{
public void runcode() {
// TODO Auto-generated method stub
for(int x = 0;x<4000;x++){
System.out.println(x);
}
}
}
接口降低了耦合性
----------------------------------------------------
Object类中已经提供了对对象是否相同的比较方法
如果自定义类中也有比较相同的功能,没必要重新定义。只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。
----------------------------------------------------------
多线程
package com.itheima;
class Test extends Thread{
// private String name;
Test(String name){
super(name);
// this.name=name;
}
public void run(){
for(int x= 0;x<60;x++){//局部变量在每一个线程区域都有独立的一份
// System.out.println(this.getName()+"test run..."+x);
System.out.println(Thread.currentThread().getName()+"run……"+x);
}
}
}
/*//创建两个线程,和主线程交替运行
*/
package com.itheima;
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test t1 = new Test("one");
Test t2 = new Test("two");
t1.start();
t2.start();
/* t1.run();
t2.run();*/
for(int x= 0;x<60;x++){
System.out.println("mian..."+x);
}
}
}
--------------------------
第二种
package com.itheima;
/*需求:买票程序,多窗口同事卖票*/
public class SaleTickets{
public static void main(String[] args) {
// TODO Auto-generated method stub
Ticket t = new Ticket();
Thread t1 = new Thread(t);//创建了一个线程;
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
/* Ticket st1 = new Ticket();
Ticket st2 = new Ticket();
Ticket st3 = new Ticket();
Ticket st4 = new Ticket();
st1.start();
st2.start();
st3.start();
st4.start();*/
/* st1.start();
st1.start();
st1.start();
st1.start();//运动员跑步,只有一个人,跑起来,跑第二圈,又开启发令枪,已经从创建状态到运行状态,再start就没意义
*/
}
}
package com.itheima;
/*创建线程的第二种方式:实现Runnable接口
步骤:
1、定义类实现Runnable接口
2、覆盖Runnable接口中的run方法
将线程要运行的代码存放在该run方法中
3、通过Thread类建立线程对象
4、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
自定义的run方法所属的对象时Runnable接口的子类对象,所以要让线程去指定对象的run方法。就必须明确该run方法所属的对象
5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
实现方式和extends区别:
避免了单继承的局限性
继承Thread:线程代码存放在Thread子类run方法中
实现RUnnable,线程代码存在接口的子类的run方法
*/
class Ticket implements Runnable/*extends Thread*/{
private int tick =100;
public void run(){
while(true){
if(tick>0){
System.out.println(Thread.currentThread().getName()+" "+"sale:"+tick--);
}
}
}
}
-------------------------------------
死锁
package com.itheima;
public class TestLock implements Runnable{
private boolean flag;
TestLock(boolean flag){
this.flag=flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
if(flag){
synchronized(MyLock.locka){
System.out.println("if locka");
synchronized(MyLock.lockb){
System.out.println("if lockb");
}
}
}
else{
synchronized(MyLock.lockb){
System.out.println("else lockb");
synchronized(MyLock.locka){
System.out.println("else locka");
}
}
}
}
}
package com.itheima;
public class MyLock {
static Object locka = new Object();
static Object lockb = new Object();
}
package com.itheima;
public class DeadLockTest {
public static void main(String[] args){
Thread t1 = new Thread(new TestLock(true));
Thread t2 = new Thread(new TestLock(false));
t1.start();
t2.start();
}
}
---------------------------------------
wait;
notify();
notifyAll();
都使用在同步中,因为要对待有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要表示他们所操作线程持有的锁。
只有同一个锁上 的被等待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒,也就是说等待和唤醒必须是同一个锁。
而锁可以是任务对象,所以可以被任意对象调用的方法定义在object类中。
-----------------------------------------------
多线程join方法:
当A线程执行到了B线程的.join()方法时,A就会等待。等B线程都执行完,A才会执行
join可以用来临时加入线程执行
-----------------------------------
优先级
.setPriority(Thread.MAX_PRIORITY)
凡是数据是固定的定义成常量,数据共享的就变成静态
.yield()
释放当前资源
package com.itheima;
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(){
public void run(){
for(int x=0;x<100;x++){
System.out.println(Thread.currentThread().getName()+"...."+x);
}
}
}.start();
for(int x=0;x<100;x++){
System.out.println(Thread.currentThread().getName()+"...."+x);
}
Runnable r = new Runnable(){
public void run(){
for(int x=0;x<100;x++){
System.out.println(Thread.currentThread().getName()+"...."+x);
}
}
};
}
}
---------------------------------------------------
内部类
当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事务在使用外部事物的内容。
eg:人体内部
class Body{
private class Xinzang{//当一个类需要直接访问到另一个类的成员的时候,把这个类写到里面去,不对外暴露,只提供方法
}
public void show(){
new Xinzang().
}
}
匿名内部类:
1、匿名内部类其实就是内部类的简写格式
2、定义匿名内部类的前提:内部类必须是继承一个类或者实现接口
3、匿名内部类的格式:new 父类或者接口(){定义子类的内容}
4、其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象
5、匿名内部类中定义的方法最好不要超过3个。
package com.itheima;
public interface Inter {
void method();
}
package com.itheima;
public class InnerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test.function().method();//。method().function这个方法运算后的结果是一个对象:Inter类型的对象才能调用method方法
}//Test.function()Test类中有一个静态的方法function
}
package com.itheima;
public class Test {
/*static class Inner implements Inter{
public void method(){
System.out.println("method run");
}
}
public static Inter function() {//确定返回值Inter
// TODO Auto-generated method stub
return new Inner();//
}
}
*/
static Inter function(){
return new Inter(){//匿名内部类,没有名字只能用父类或者接口代替
public void method(){
System.out.println("method run");
}
};
}
}
当没有父类和接口的时候
class InnerTest{
public static void main(String[] args){
new Object(){
public void function(){
}.function();
}
}
}