java语法基础(四)

时间:2023-03-10 06:39:07
java语法基础(四)

继承

  继承概述

  继承是面向对象语言的三大基本特性(封装,继承,多态)之一。 一个类可以继承另外一个类,继承的类称为子类(也可以叫派生类),被继承的类称为父类(或者也叫基类,超类)。 通过继承,子类可以享有父类的成员(变量/方法),节省代码的书写。

  继承的实现

  在java中,通过extends关键字,描述继承关系。 代码书写格式: class 子类名 extends 父类名{ }

  //人类 class Person{ String name; private int age; public Person(String name){ this.name = name; } public Person(){ System.out.println("Person类的构造方法被调用了...."); } public void eat(){ System.out.println(name+"在吃饭..."); } } //学生类 class Student extends Person { // Student 就称作为Person类的子类, Person类就称作为Student的父类(超类、基类) int num; //学号 public Student(){ System.out.println("Student类的构造方法被调用了...."); } public void study(){ System.out.println(name+"good good study , day day up"); } } class Demo7 { public static void main(String[] args) { Student s = new Student(); /* s.name = "狗娃"; System.out.println("名字:"+ s.name); s.eat(); */ } }

  继承注意事项

  1. 千万不要为了减少重复代码而去继承,只有真正存在着继承关系的时候才去继承。 2. 父类私有的成员不能被继承。 3. 父类的构造函数不能被继承。 4. 创建子类对象时默认会先调用父类无参的构造函数。

  疑问: 为什么要调用父类的构造方法啊?这样子做的意义在那? 调用父类 的构造方法是可以初始化从父类继承下去的属性的。

super关键字

  super关键字: super关键字代表了父类空间的引用。 super关键字的 作用: 1. 子父类存在着同名的成员时,在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员。 2. 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法。 super关键字调用父类构造方法要注意的事项: 1. 如果在子类的构造方法上没有指定调用父类的构造方法,那么java编译器会在子类的构造方法上面加上super()语句。 2. super关键字调用父类的构造函数时,该语句必须要是子类构造函数中的第一个语句。 3. super与this关键字不能同时出现在同一个构造函数中调用其他的构造函数。因为两个语句都需要第一个语句。

java语法基础(四)

  super关键字和this关键字的区别: 1. 代表的事物不一致。 1. super关键字代表的是父类空间的引用。 2. this关键字代表的是所属函数的调用者对象。 2. 使用前提不一致。 1. super关键字必须要有继承关系才能使用。 2. this关键字不需要存在继承关系也可使用。 3. 调用构造函数的区别: 1. super关键字是调用父类的构造函数。 2. this关键字是调用本类的构造函数。

方法重写

  当父类的功能无法满足子类的需求。我们可以使用方法重写重新定义方法。方法重写的前提是必须要存在继承的关系。 方法的重写: 子父类出了同名的函数,这个我们就称作为方法的重写。 方法重写要注意的事项: 1.方法重写时, 方法名与形参列表必须一致。 2.方法重写时,子类的权限修饰符必须要大于或者等于父类的权限修饰符。 3.方法重写时,子类的返回值类型必须要小于或者 等于父类的返回值类型。 4.方法重写时, 子类抛出的异常类型要小于或者等于父类抛出的异常类型。 相比而言方法的重载:在一个类中 存在两个或者两个 以上的同名函数,称作为方法重载。 方法重载的要求 1. 函数名要一致。 2. 形参列表不一致(形参的个数或形参 的类型不一致) 3. 与返回值类型无关。

instanceof关键字

  instanceof 关键字:可以用来判断一个对象是否属于指定的类别。要求判断的对象与指定的类别必须要存在继承或者实现的关系。 代码书写格式: 对象 instanceof 类别 一般我们做强制类型转换之前都会使用该关键字先判断一把,然后在进行转换的。

final关键字

  final:表示最终的。 final关键字的用法: 1. final关键字修饰一个基本类型的变量时,该变量不能重新赋值,第一次的值为最终的。 这种情况下相当于声明了一个常量。而且必须进行初始化。 2. final关键字修饰一个引用类型变量时,该变量不能重新指向新的对象。 3. final关键字修饰一个函数的时候,该函数不能被重写。 4. final关键字修饰一个类的时候,该类不能被继承。 注意:常量 的修饰符一般为: public static final

抽象类

  抽象类:使用了关键词abstract声明的类叫作“抽象类”。 抽象类的应用场景: 在描述一类事物的时候,发现该事物确实存在着某种行为,但是这种行为目前是不具体的,那么我们可以抽取这种行为的声明,但不去实现该种行为;这时候这种行为我们称作为抽象的行为,这个类就需要使用抽象类。 抽象类要注意的细节: 1. 如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象 的函数。。 2. 如果一个类出现了抽象的函数,那么该类也必须 使用abstract修饰。 3. 如果一个非抽象类继承了抽象类,那么必须要把抽象类的所有抽象方法全部实现。 4. 抽象类可以存在非抽象方法,也可以存在抽象的方法. 5. 抽象类可以不存在抽象方法的。 5. 抽象类是不能创建对象的。 6. 抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的。 7,抽象类不能够创建对象。 抽象类的好处: 强制要求子类一定要实现指定的方法。

  应用场景举例: 我们写一个动物类,每个动物都有趋利避害的特性,所以动物都应该有逃跑的功能。但是狗有狗的逃法,乌龟有乌龟的逃法,鱼有鱼的逃法。那么这个动物类的逃跑该怎么实现呢? 我们可能面临的问题 1. 动物类的runAway方法描述的不正确。 2. 没有强制要子类一定要重写run方法。

  练习: 定义一个图形类,圆形类,矩形类,要求图形类有打印自己周长和面积的功能

  abstract不能与以下关键字共同修饰一个方法: 1. abstract不能与private共同修饰一个方法。 2. abstract 不能与static共同修饰一个方法。 3. abstract 不能与final共同修饰一个方法。

值类型和引用类型的区别

  调用函数传递参数,其实传递的是变量的值。

java语法基础(四)

java语法基础(四)

接口

  在java中,一个类最多只能有一个直接的父类,可以有多个间接的父类。java属于是单继承的。 需求:拖拉机可以奔跑,播种机可以耕种,现在想要一台能够耕种的拖拉机,该怎么声明? java虽然不能多继承,但是可以多实现,这就需要我们学习接口的知识。

  接口的定义格式: interface 接口名{ } 实现接口的格式: class 类名 implements 接口名{ }

  接口要注意的事项 : 1. 接口是一个特殊的类。 2. 接口的成员变量默认的修饰符为: public static final 。那么也就是说接口中的成员变量都是常量。 3. 接口中 的方法都是抽象的方法,默认的修饰符为: public abstract。 4. 接口不能创建对象。 5. 接口是没有构造方法的。 6. 接口是给类去实现使用的,非抽象类实现一个接口的时候,必须要把接口中所有方法全部实现。

  接口的作用: 1 程序解耦,这个很最重要的作用 2 定义约束规范 3 拓展功能

类,接口之间的关系

  类与接口之间关系: 实现关系。 类与接口要注意的事项: 1. 非抽象类实现一个接口时,必须要把接口中所有方法全部实现。 2. 抽象类实现一个接口时,可以实现也可以不实现接口中的 方法。 3. 一个类可以实现多个接口 。不同接口之间用,分割 接口与接口之间关系: 继承关系。 接口与接口之间要注意事项: 1. 一个接口是可以继承多个接口的。

多态

  面向对象的三大特征: 1. 封装 2. 继承。 3. 多态 多态:是面向对象的三大特征之一,具体说就是允许将子类类型的对象地址赋值给父类类型的指针,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。java中也可以是接口 的引用类型变量指向了接口实现类的对象) 多态的前提:必须存在继承或者实现 关系。

  多态要注意 的细节: 1. 多态情况下,子父类存在同名的成员变量时,访问的是父类的成员变量。 2. 多态情况下,子父类存在同名的非静态的成员函数时,访问的是子类的成员函数。 3. 多态情况下,子父类存在同名的静态的成员函数时,访问的是父类的成员函数。 4. 多态情况下,不能访问子类特有的成员。 前三条可以归总为:子父类存在同名的成员时,访问的都是父类的成员,除了在同名非静态函数时才是访问子类的。

  编译看左边,运行不一定看右边。 编译看左边:java编译器在编译的时候,会检查引用类型变量所属的类是否具备指定的成员,如果不具备马上编译报错。

  多态的应用: 1. 多态用于形参类型的时候,可以接收更多类型的数据 。 2. 多态用于返回值类型的时候,可以返回更多类型的数据。 多态的好处: 提高了代码的拓展性。

  接口形势下,多态的实现 代码格式: 接口名称 变量名 = new 实现类();

class Test { public static void main(String[] args) { AirCondition aAirCondition = new HaierAirCondition(); aAirCondition.start(); } } interface AirCondition { public void start(); } class HaierAirCondition implements AirCondition { public void start(){ System.out.println("开始启动"); } }

内部类,匿名内部类

  内部类

  内部类:定义在类的内部的类,称为内部类。我们在描述事物的时候,发现所描述的事物内部还存在另外一个比较复杂的事物时候,而且这个比较复杂事物还需要访问本事物的属性等数据,那么这时候我们就可以使用内部类描述复杂事物。 内部类分为: 1 成员内部类 2 局部内部类:局部内部类,匿名内部类 内部类的好处:内部类可以直接访问外部类的所有成员。 内部类要注意的细节: 1. 内部类经过编译以后,也会得到一个class文件,名字为: 外部类$内部类 2. 如果外部类与内部类存在同名的成员变量时,在内部类中默认情况下是访问内部类的成员变量。 可以通过"外部类.this.成员变量名" 指定访问外部类的 成员。 3. 私有的成员内部类只能在外部类提供一个方法创建内部类的对象进行访问,不能在其他类创建对象了。 4. 成员内部类一旦出现了静态的成员,那么该类也必须 使用static修饰。

  成员内部类:把内部类声明在外部类成员的位置,称为成员内部类。 成员内部类的访问方式: 方式一:在外部类提供一个方法创建内部类的对象进行访问。 方式二:在其他类直接创建内部类的对象。 格式:外部类.内部类 变量名 = new 外部类().new 内部类(); 注意: 如果是一个静态内部类,那么在其他类创建 的格式: 外部类.内部类 变量名 = new 外部类.内部类();

  class Test { public static void main(String[] args) { Car bmw = new Car(); bmw.start(); //Car.Engine aE = bmw.new Engine("002"); //aE.run(); } } class Car { String brand; public void start(){ System.out.println("启动"); Engine e=new Engine("001"); e.run(); } public static class Engine { static int id; String name; Engine(String name){ this.name = name; } float runSpeed; public void run(){ System.out.println(name + "旋转"); } } }

  局部内部类: 在一个类 的方法内部定义一个类,那么这个类就称作为局部内部类。 局部内部类要注意的细节: 1. 如果局部 内部类访问了一个局部变量,那么该局部变量必须使用final修饰。

  class Demo2 { public static void main(String[] args) { Lamp l = new Lamp(); l.on(); } } class Lamp { public void on(){ System.out.println("打开灯"); int vate = 15; class Bulb { public void light(){ System.out.println("灯泡发光了"); } public void hot(){ System.out.println("灯泡发热了"+vate); } } Bulb b = new Bulb(); b.light(); b.hot(); } }

  匿名内部类:没有类名的类就称作为匿名内部类。 匿名内部类的使用前提:必须存在继承或者实现关系才能使用。 匿名内部类的好处:简化书写。 匿名内部类一般是用于实参。

  继承关系下的匿名内部类

  实现关系下的匿名内部类

class Demo3 { public static void main(String[] args) { Lamp l = new Lamp(); l.on(); } } interface Bulb { public void light(); } class Lamp { public void on(){ System.out.println("开灯"); /* 局部内部类 class LedBulb extends Bulb { public void light(){ System.out.println("点亮LED"); } } LedBulb ledB = new LedBulb(); ledB.light(); */ //匿名内部类 lightBulb(new Bulb(){ public void light(){ System.out.println("点亮LED"); } }); } public void lightBulb(Bulb b){ b.light(); } }

异常

  异常

  异常: 现实生活中,很多人都会生病去医院。病也分很多种 1 不治之症:艾滋病 2 可以治疗的病: A 不去医院自己治疗的病:小感冒,小擦伤 B 一定要去医院治疗的病:阑尾炎 我们的java程序也是会存在某些不正常 的情况的,这些不正常的 情况我们就统称异常。java中是一种面向对象的语言,任何事情都用类描述,所以java中描述异常的类,我们称为异常类。所有描述异常的类堆积在一起,就构成了我们异常体系。 异常的体系: ----------| Throwable 所有异常或者错误类的超类 --------------|Error 错误 错误一般是用于jvm或者是硬件引发的问题,所以我们一般不会通过代码去处理错误的。 --------------|Exception 异常 是需要通过代码去处理的。 体系盖怎么学习呢?一般情况我们会从上往下学习。既然很多类都在继承,那么学习了基类能帮助快速理解子类的方法。

  我们常见的错误和异常 错误一般是由于java虚拟机导致的,所以一般不会通过修改代码来修改错误,异常一般是由代码引起的,可以通过代码修改。

   javac 类名写错时候会报错

  内存不足,错误 byte[] buf = new byte[1024*1024*1024];

  数组越界异常 class Test { public static void main(String[] args) { System.out.println(args[0]); } }

  空指针异常 public static void main(String[] args) { Test a = null; a.run(); } public void run(){ System.out.println("xx"); }

  Throwable常用的方法: toString() 返回当前异常对象的完整类名+病态信息。 getMessage() 返回的是创建Throwable传入的字符串信息。 printStackTrace() 打印异常的栈信息。

  public static void main(String[] args) { /* //创建了一个Throwable对象。 Throwable t = new Throwable("头晕,感冒.."); String info = t.toString(); String message = t.getMessage(); System.out.println("toString: "+ info); // java.lang.Throwable 包名+类名 = 完整类名 System.out.println("message: "+ message); */ test(); } public static void test(){ // Throwable t = new Throwable(); t.printStackTrace(); }

  如何区分错误与异常呢: 如果程序出现了不正常的信息,如果不正常的信息的类名是以Error结尾的,那么肯定是一个错误。 如果是以Exception结尾的,那么肯定就是一个异常。

  public static void main(String[] args) { //java虚拟机在默认的情况下只能管理64m内存。 byte[] buf = new byte[1024*1024]; System.out.println("Hello World!"); }

  异常处理: 方式一:捕获处理 捕获处理的格式: try{ 可能发生异常的代码; }catch(捕获的异常类型 变量名){ 处理异常的代码.... } 捕获处理要注意的细节: 1. 如果try块中代码出了异常经过了处理之后,那么try-catch块外面的代码可以正常执行。 2. 如果try块中出了异常的代码,那么在try块中出现异常代码后面的代码是不会执行了。 3. 一个try块后面是可以跟有多个catch块的,也就是一个try块可以捕获多种异常的类型。 4. 一个try块可以捕获多种异常的类型,但是捕获的异常类型必须从小到大进行捕获,否则编译报错。 我们没有创建异常对象,那么这个抛出的异常其实是jvm发现异常以后创建并且抛出的。 疑问一 : 异常的处理感觉没有多大作用,因为都是输出一个话而已? 异常处理非常有用,只不过是由于我们目前所接触的知识点太过于局限而已。 疑问二: 以后捕获处理 的时候是否就是捕获Exception即可? 错的,因为我们在现实开发中遇到不同的异常类型的时候,我往往会有不同 的处理方式。 所以要分开不同的异常类型处理。

  public static void main(String[] args) { int[] arr = null; div(4,0,arr); } public static void div(int a , int b,int[] arr){ int c = 0; try{ c = a/b; //jvm在这句话的时候发现了不正常的情况,那么就会创建一个对应的异常对象。 System.out.println("数组的长度:"+ arr.length); }catch(ArithmeticException e){ //处理异常的代码.... System.out.println("异常处理了...."); System.out.println("toString:"+ e.toString()); }catch(NullPointerException e){ System.out.println("出现了空指针异常...."); }catch(Exception e){ System.out.println("我是急诊室,包治百病!"); } System.out.println("c="+c); }

  异常的处理方式----抛出处理 抛出处理(throw throws) 抛出处理要注意的细节: 1. 如果一个方法的内部抛出了一个异常 对象,那么必须要在方法上声明抛出。 2. 如果调用了一个声明抛出异常 的方法,那么调用者必须要处理异常。如果不想处理,那么调用的方法也抛出一个异常。 3. 如果一个方法内部抛出了一个异常对象,那么throw语句后面的代码都不会再执行了(一个方法遇到了throw关键字,该方法也会马上停止执行的)。 4. 在一种情况下,只能抛出一种类型异常对象。 throw 与throws两个关键字: 1. throw关键字是用于方法内部的,throws是用于方法声声明上的。 2. throw关键字是用于方法内部抛出一个异常对象的,throws关键字是用于在方法声明上声明抛出异常类型的。 3. throw关键字后面只能有一个异常对象,throws后面一次可以声明抛出多种类型的 异常。 疑问:何时使用抛出处理?何时捕获处理?原则是如何? 如果你需要通知到调用者,你代码出了问题,那么这时候就使用抛出处理. 如果代码是直接与用户打交道遇到了异常千万不要再抛,再抛的话,就给了用户了。 这时候就应该使用捕获处理。

  public static void main(String[] args) { try{ int[] arr = null; div(4,0,arr); //调用了一个 声明抛出异常类型 的方法 }catch(Exception e){ System.out.println("出现异常了..."); e.printStackTrace(); } } public static void div(int a, int b,int[] arr) throws Exception,NullPointerException { if(b==0){ throw new Exception(); //抛出一个异常对象... }else if(arr==null){ throw new NullPointerException(); } int c = a/b; System.out.println("c="+c); }

  自定义异常类

  自定义一个类继承Exception即可

//自定义了一个没有网线的异常类了。 class NoIpException extends Exception{ public NoIpException(String message){ super(message); //调用了Exception一个参数的构造函数。 } } class Demo2 { public static void main(String[] args) { String ip = "192.168.10.100"; ip = null; try{ feiQ(ip); // 如果调用了一个声明抛出异常类型的方法,那么调用者必须要处理。 }catch(NoIpException e){ e.printStackTrace(); System.out.println("马上插上网线!"); } } public static void feiQ(String ip) throws NoIpException{ if(ip==null){ throw new NoIpException("没有插网线啊,小白!"); } System.out.println("正常显示好友列表.."); } }

/* 需求:模拟你去吃木桶饭,如果带钱少于了10块,那么就抛出一个没有带够钱的异常对象, 如果带够了,那么就可以吃上香喷喷的地沟油木桶饭. */ //定义没钱的异常 class NoMoneyException extends Exception { public NoMoneyException(String message){ super(message); } } class Demo3 { public static void main(String[] args) { //System.out.println("Hello World!"); try{ eat(9); }catch(NoMoneyException e){ e.printStackTrace(); System.out.println("跟我洗碗一个月!!"); } } public static void eat(int money) throws NoMoneyException{ if(money<10){ throw new NoMoneyException("吃霸王餐"); } System.out.println("吃上了香喷喷的地沟油木桶饭!!"); } }

  运行时异常 和 编译时异常

异常体系: --------| Throwable 所有错误或者异常的父类 --------------| Error(错误) --------------| Exception(异常) 异常一般都通过代码处理 ------------------| 运行时异常: 如果一个方法内部抛出了一个运行时异常,那么方法上 可以声明也可以不 声明,调用者可以以处理也可以不处理。 ------------------| 编译时异常(非运行时异常、受检异常): 如果一个方法内部抛出了一个编译时异常对象,那么方法上就必须要声明,而且调用者也必须要处理。 运行时异常: RuntimeException以及RuntimeException子类 都是属于运行时异常。 编译时异常: 除了运行时异常就是编译异常。 疑问: 为什么java编译器会如此严格要求编译时异常,对运行时异常如此宽松? 运行时异常都是可以通过程序员良好的编程习惯去避免,所以java编译器就没有严格要求处理运行时异常。

import java.security.acl.*; class Demo4 { public static void main(String[] args) throws InterruptedException { int[] arr = null; div(4,0,arr); Object o = new Object(); o.wait(); } public static void div(int a , int b ,int[] arr) { if(b==0){ return; } int c = a/b; System.out.println("c = "+c); if(arr!=null){ System.out.println("数组的长度: "+arr.length); } } }

finally块

finally 块; finally块的 使用前提是必须要存在try块才能使用。 finally块的代码在任何情况下都会执行的,除了jvm退出的情况。 finally非常适合做资源释放的工作,这样子可以保证资源文件在任何情况下都 会被释放。 try块的三种组合方式: 第一种: 比较适用于有异常要处理,但是没有资源要释放的。 try{ 可能发生异常的代码 }catch(捕获的异常类型 变量名){ 处理异常的代码 } 第二种:比较适用于既有异常要处理又要释放资源的代码。 try{ 可能发生异常的代码 }catch(捕获的异常类型 变量名){ 处理异常的代码 }finally{ 释放资源的代码; } 第三种: 比较适用于内部抛出的是运行时异常,并且有资源要被释放。 try{ 可能发生异常的代码 }finally{ 释放资源的代码; }

class Demo5 { public static void main(String[] args) { //System.out.println("Hello World!"); div(4,0); } public static void div(int a, int b){ try{ if(b==0){ System.exit(0);//退出jvm } int c = a/b; System.out.println("c="+ c); }catch(Exception e){ System.out.println("出了除数为0的异常..."); throw e; }finally{ System.out.println("finall块的代码执行了.."); } } }

/* fianlly释放资源的代码 */ import java.io.*; class Demo6 { public static void main(String[] args) { FileReader fileReader = null; try{ //找到目标文件 File file = new File("f:\\a.txt"); //建立程序与文件的数据通道 fileReader = new FileReader(file); //读取文件 char[] buf = new char[1024]; int length = 0; length = fileReader.read(buf); System.out.println("读取到的内容:"+ new String(buf,0,length)); }catch(IOException e){ System.out.println("读取资源文件失败...."); }finally{ try{ //关闭资源 fileReader.close(); System.out.println("释放资源文件成功...."); }catch(IOException e){ System.out.println("释放资源文件失败...."); } } } }

java包

  包: java中的包就相当于windows文件夹。 包的作用: 1. 解决类名重复产生冲突的问题。 2. 便于软件版本的发布。 定义包的格式: package 包名; 包名命名规范:包名全部小写。 包语句要注意的事项: 1. package语句必须位于java文件中中第一个语句。 2. 如果一个类加上了包语句,那么该类的完整类名就是: 包名.类名 3. 一个java文件只能有一个包语句。 问题: 每次编译的时候都需要自己创建一个文件夹,把对应 的class文件存储 到文件夹中。太麻烦 javac -d 指定类文件的存放路径 java源文件

  package aa; class Demo1 { public static void main(String[] args) { System.out.println("这个是Demo1的main方法..."); } }

  问题: 有了包之后类与类之间的访问每次都必须 要写上包名!太麻烦 解决方案: sum提供导包语句让我们解决该问题。 导包语句作用:简化书写。 (误区: 把一个类导入到内存中) 导包语句的格式: import 包名.类名; (导入xxx包中某个类) 导包语句要注意的细节: 1. 一个java文件中可以出现多句导包语句。 2. "*"是 导包语句的通配符。可以匹配任何 的类名。 3. import aa.*; 是不会作用于aa包下面的子包的。 推荐使用:import 包名.类名; 因为使用*通配符会导致结构不清晰。 什么时候使用import语句: 1. 相互访问的两个类不是在同一个包下面,这时候就需要使用到导包语句。 2. java.lang 是默认导入 的,不需要我们自己导入。

  通过静态代码块判断导包的含义 package aa; public class Demo3 { /* static{ System.out.println("这个是Dmeo3的静态代码块..."); } */ public void print(){ System.out.println("这个是Dmeo3的print方法..."); } }

权限修饰符

  权限修饰符: 权限修饰符就是控制被修饰的成员的范围可见性。 public(公共) protected(受保护) default(缺省) private (大到小) 同一个类 true true true true 同一个包 true true true false 子父类 true true false false 不同包 true false false false 注意: 在不同包下面只有public 与 protected 可以访问,而且protected必须是在继承关系下才能够访问。

打jar包

  我们给到用户的产品不应该是一大群class文件。一般情况下我们会打包成jar包给用户使用。 打jar包: 需要使用到jdk的开发工具(jar.exe). jar命令的用法: 使用格式: jar cvf jar文件的名字 class文件或者是文件夹 jar cvf test.jar test.java 打jar包前要先将java文件编译成class文件或者包。 打jar包要注意的事项: 1. 一个程序打完了jar之后 必须要在清单文件上指定入口类: 格式 Main-Class: 包名.类名 2. jar包双击运行仅对于图形化界面的程序起作用,对控制台的程序不起作用。 jar文件的作用: 1. 方便用户快速运行一个项目。 2. 提供工具类以jar包的形式给别人使用。 如果使用jar包里面的类必须要先设置classpath路径。 jre = jvm+ 核心类库

  package qq; import javax.swing.*; class Demo9 { public static void main(String[] args) { System.out.println("QQ程序.."); JFrame frame = new JFrame("QQ程序"); frame.setSize(400,500); frame.setVisible(true); //设置窗口可见。 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

模版模式

  模板模式 :解决某类事情的步骤有些是固定的,有些是会发生变化的,那么这时候我们可以为这类事情提供一个模板代码,从而提高效率 。 需求;编写一个计算程序运行时间 的模板。 模板模式的步骤: 1. 先写出解决该类事情其中 的一件的解决方案。 2. 分析代码,把会发生变化的代码抽取出来独立成一个方法。把该方法描述成一个抽象的方法。 3. 使用final修饰模板方法,防止别人 重写你的模板方法。

abstract class MyRuntime{ public final void getTime(){ long startTime = System.currentTimeMillis(); //记录开始的时间 code(); long endTime = System.currentTimeMillis(); //记录结束的时间. System.out.println("运行时间 :"+ (endTime-startTime)); } public abstract void code(); } class Demo11 extends MyRuntime { public static void main(String[] args) { Demo11 d = new Demo11(); d.getTime(); } //code方法内部就写要计算运行时间 的代码; public void code(){ int i = 0; while(i<100){ System.out.println("i="+i); i++; } } }