Java学习笔记6

 
======================================================================
Java  
6:  Java高级特性
修饰符;接口,内部类,对象,包装类,集合,异常处理,反射.
======================================================================
(1)
修饰符。
private,default,protected,public //
不能修饰局部变量
private,default,protected,public:
都能修饰属性和方法,
但是只有default,public能修饰类.
表1:类,方法,成员变量和局部变量的可用修饰符
   修饰符  
         
成员方法
构造方法
成员变量
局部变量
abstract
static
public
protected
private
synchronized
native
transient(暂时的)
volatile(易失的)
final
 
 2 : 访问的级别和可访问范围
访问级别
访问控制修饰参数
同类
同包
子类
不同的包
公开
Public
受保护
Protected
默认
Default(没有修饰)
私有
private

(2) static //
静态的.  
能修饰属性,方法,初始代码块.
package test;
publicclass TestStatic {
publicstaticvoid main(String[] args){
       MyClass mc1=new MyClass();
       MyClass mc2=new MyClass();
       mc1.a=10;
       System.out.print("mc1.a="+mc1.a);
       System.out.print("mc2.a="+mc2.a);
       mc2.a=20;
       System.out.print("mc1.a="+mc1.a);
       System.out.print("mc2.a="+mc2.a);
       System.out.print("MyClass.a="+MyClass.a); // 因为a是类变量,所以可以用类名调用.
       System.out.println(); // outSystem里的公有的属性.
              MyClass.m1(); // 类名调用.
       }
}
class MyClass{
       staticinta=1; // 此时叫类变量,全类公有.因此可以用类名调用.
       intb=2; // 创建对象的时候才分配空间,初始化.
       publicstaticvoid m1(){
              System.out.println(a);
              System.out.println(b);//静态方法不能访问非静态属性。
       }
       publicstaticvoid m2(){ // 相当于全类的,因此能用类名调用.是打破面向对象思想的.
              System.out.println(a);
              System.out.println(b);// 编译错误,静态方法不能访问非静态属性.因为,
       }
}
属性: 类变量(static),实例变量.
局部变量不是属性.
(4)
静态方法是否能覆盖?
静态方法可以覆盖,但是必需是静态方法覆盖静态方法,非静态方法不能覆盖静态方法.(此时就没有了多态.)
package test;
class TestOverride{
       publicstaticvoid main(String[] args){
       Super s=new Sub();//只有非静态方法的覆盖才有多态.
       System.out.println(s.a); // =10
       }
}
class Super{
       staticinta=10;
}
class Sub extends Super{
       staticinta=20;
}
(5)
静态属性是在什么时候,被初始化的???
: 在类加载的时候被初始化的.
(7)
什么叫类加载??
: 类加载一次,然后就创建静态变量.(也就是只创建一次).如果创建对象就不用再次的加载类,在然后就创建对象.一个类在编译之后会形成.class文件,存储了类的全部消息.JVM第一次需要用到这个类的时候,会根据ClassPath找到这个.class文件,用输入流把文件中的消息读入JVM并保存起来,这样,JVM"认识"了这个类.
类加载时机: 第一次用这个类的时候.
1.
第一次创建类的对象,会加载
2.
访问类的静态成员,会加载.
3.
声明类的引用,不会加载.
4.
加载子类,必然先加载父类
5.
如果调用的是子类从父类中继承到静态方法,只会加载父类.
6.
如果访问的是类的静态常量,如果在编译的时候能确定这个常量的值,则运行时不会加载,否则,编译是无法确定常量的值,那么运行是就会加载.
(8)
主方法为什么是静态方法?
: 如果不是静态的.必需先创建类对象,但是此时创建对象的方法是main方法里面,这样会造成矛盾.也就是不能创建对象.要解决这个问题就要把main方法写成静态的,要让main方法在创建对象之前调用(因为静态方法和属性是在类加载的时候就调用的,因此可以解决这个问题,呵呵)
(9)static
的第三种用法.(温馨提示:static 的前三种用法是:1.修饰属性,2.方法,3.初始化代码块)
//
此时而初始化代码块只能用static 修饰,嘻嘻记住吧!!!
在第三步:调用初始代码块:在构造方法前面运行,在初始化属性的时候运行。
在前面加static 静态初始代码快.在类加载的时候运行,创建对象的时候不运行这个代码块.//太有用了!!呵呵.
重要用处: 监控虚拟机的类加载.
1.
创建对象的时候会出现.
2.
第一次访问静态方法,属性.
3.
声明一个类的一个引用,不会加载类. 虚拟机有延迟加载的功能,(能不加载就不加载,也就是编译器能确定的事情[也就是不变的量,final修饰],就不会加载类,这样会浪费内存)
4.
加载子类的时候会加载父类么????
: 不单要加载父类而且会先加载父类.
例子: 看老师的代码: TestClassLoad.java
5.
如果你调用从父类继承到的静态方法,只加载父类不加载子类.
例子:例子: 看老师的代码: TestClassLoad.java
如果覆盖了父类的静态方法,就还要加载子类.
5个特性都在下面的代码中:
package test;
publicclass TestClassLoad{
       publicstaticvoid main(String[] args){
//   Student s=new Student();
//   Student.m();
//   Student s=null;
//   Sub s=new Sub();
//   Sub.m();
//   System.out.println(ClassA.A);//这个就不会调入虚拟机.(编译器当时就确定了这个数,因此就没有必要加载这个类,会省下内存空间,呵呵)
       System.out.println(ClassA.B);//此时会加载类.因为Math.random();的值不确定,要进入类才能知道.
       }
       }
       class Student{
       static{ //修饰的初始化代码块.[温馨提示: 此时只能用static 修饰,不能用private,protect,public 修饰,嘻嘻]
       System.out.println("Load Student");
       }
       staticinta;
       publicstaticvoid m(){}
       public Student(){}
       }
       class Super{ //验证[加载子类的时候会加载父类么]
       static{
       System.out.println("Load Super");
       }
       publicstaticvoid m(){}
       }
       class Sub extends Super{
       static{
       System.out.println("Load Sub");
       }
       }
       class ClassA{ //验证编译器确定了变量的值,就不会加载类
       static{
       System.out.println("Load ClassA");
       }
       publicstaticfinalintA=2*5; //确定不会变的量.
       publicstaticfinaldoubleB=Math.random(); //只有调入这个类才能确定的量.
}
(10) 和静态有关的模式模式: GOF green of four; 23种模式
1.单例模式: (yi) 一个类只允许他有一个对象.怎么实现??
就要用到单例模式.
具体例子: 这样一个类才只能有一个对象. 实现了这个需求.呵呵.
package test;
 
publicclass TestClassLoad{
       publicstaticvoid main(String[] args){
       LaoGong lg1=LaoGong.newInstance();
       LaoGong lg2=LaoGong.newInstance();
       LaoGong lg3=new LaoGong();// 这个会出现编译错误,把无参的构造方法变成私有。
       LaoGong lg4=LaoGong.newInstance();// 只有这样才能编译通过.
       System.out.println("");
       }
}
class LaoGong{
       privatestaticLaoGonglg=new LaoGong(); // 单例模式;
       publicstatic LaoGong newInstance(){//返回申请的同一个对象。lg;
              returnlg;
       }
       private LaoGong(){}// LaoGong lg=new LaoGong()路给堵上.
}
虚拟机机制: 一般来说一个类只加载一次.
java 起动一个虚拟机.
(11) 如果设计一个方法,不需要对象.就用static 修饰.一般用于JDK的工具类的。
(12) final
修饰变量.3个变量都能修饰 ,还能修饰类.
//对于类常量,初始化或者静态初始化代码块中可以赋值.

1. final 修饰变量
这个变量就变成了常量(一旦赋值,以后就不能改变了)//和conste一样,来定义常量.final修饰的变量有两次赋值的机会:申请变量的时候,在构造函数中。
package test;
publicclass TestFinal {
       publicstaticvoid main(String[] args) {
              ClassA cs = new ClassA();
              System.out.println(cs.B); // 这样会编译错误. 没有初始化,因为final要进行初始化。
              cs.B = 10; // 无法为最终变量B指定值.因此要在创建对象时赋值。.
       }
}
class ClassA {
       finalint B; // 如果,加了final 默认值无效. 因为是常量所以要是大写.
       finalint B = 10;// 第一种赋值的方法.
       public ClassA(){}
       public ClassA(int b) { // 第二种赋值方法.
              this.B = B;
       }
       publicvoid m() {
              int a = 10;
              a = 20;
       }
}
2. final 修饰类和方法.
例子: 修饰类,则这个类没有子类,如果一个类用final修饰,那么这个类不能被继承.
final class Super{ //编译错误, 无法从最终类继承.例子: String 类是一个final.
public final void m(){} // 如果一个类用final修饰,那么这个类不能被继承.
}
//final 的用处: 自己写的方法,不希望被子类修改,保持了方法的稳定性.
class Sub extends Super{
public void m(){}//编译错误.无法覆盖因为被覆盖的方法是 final.
}
//判断: 一个final类的其中所有的方法全是final ????? 对了,呵呵.
public static final double A=3.14//公开静态常量.
======================================================================
package test;
publicclass TestFinal {
       publicstaticvoid main(String[] args) {
              ClassA cs = new ClassA();
              System.out.println(cs.A);// 编译器在编译的时候System.out.println(10);10
                                                               // 是静态常量.因此不会加载ClassA();
              System.out.println(cs.B);// 编译器在编译的时候不能确定B的值,因此会加载ClassA();
       }
}
class ClassA {
       static {
              System.out.println("Load ClassA");
       }
       publicstaticfinalintA = 2 * 5;//编译器能确定,因此就不装载子类了。
       publicstaticfinaldoubleB = Math.random();//编译器不能确定此时的值,因此要装载子类。
}
======================================================================
(14) abstract 表示抽象的 修饰类,方法,抽象类:用来被继承.
抽象方法:只有定义没有实现.如果一个类里边有抽象方法,这个类必需是抽象类.一个抽象类,并不一定有抽象方法.
抽象类有构造方法
通过abstract,我们可以把一个方法定义
例子:
package test;
publicclass TestAbstact{
       publicstaticvoid main(String[] args){
       Super s=new Super();// 是抽象的不能去创建对象,因此不能作为运行时类型.
       Super s;// 可以声明引用.他是用来被继承的.
       Super s=new Sub();// 可以,抽象类可以作为一个类的半成品.(抽象类作为编译时类型,子类作为运行时类型.)
       s.m();// 找子类中实现的方法.
       }
       }
abstractclass Super{
       publicabstractvoid m(); // 抽象方法,只有声明没有实现.
       }
class Sub extends Super{// 如果不实现他,就不会编译通过,嘻嘻,必需全部实现父类的抽象方法.
       publicvoid m(){
       System.out.println("hehe"); // 实现了父类的这个方法.呵呵.
       }
}
final abstract 都不能修饰构造方法.
======================================================
(14) 修饰符的组合方式;final abstract 都不能修饰构造方法.
抽象类,可以有构造方法,是让子类调用的.
但是,接口没有构造方法.
private ,static,final 可以任意的组合,去修饰一个方法.
三个任意一个都不能和abstract 和用在一起.
private
static          
不能混用         abstract
final

---------------------------------------------
抽象方法的作用:
======================================================================
(15) 接口语法:
1. 一个接口就是一个抽象类,而且是一个特殊的抽象类,所有属性默认都是公开静态常量,所有的方法默认都是公开抽象方法.接口之间可以多继承.一个类在继承另外一个类的同时,还可以实现多个接口,
2. 一个类实现一个接口,如果这个类不是抽象类的化,那么就一定要实现接口中定义的方法.
3. 接口没有构造方法.
例子:
package test;
publicclass TestInterface{
       publicstaticvoid main(String[] args){
       Impl i=new Impl();
       MyClass mc=i;
       mc.m6();// 只能调用m6();
       IA ia=i;ia.m1();ia.m2();
       IB ib=i;ib.m3();
       IC ic=i;ic.m1();ic.m2();ic.m3();ic.m4();
       ID id=i;is.m5();
       }
}
abstractclassAbstractClass{ // 接口是特殊的抽象类
       publicabstractvoid m1();
}
class Sub extends Super{
       publicstaticfinalintA=10;
       publicabstractvoid m1();
       publicabstractvoid m2();
}
interface IA{ // 此接口和上一个抽象类在逻辑上是完全等价的.
       inta=10;// 接口的属性.接口中属性公开静态常量.
// 接口中没有构造方法.
       void m1();// 接口中所有的方法都是公开抽象方法.
       void m2();
}
interface IB{//
       void m3();
}
interface IC extends IA,IB{// 接口能够继承.而且能够多继承.
       void m4();
}
interface ID{ //
       void m5(); //
}
class Impl extends IA{ // 错误,类和类之间有继承,接口和接口之间有继承,类和接口之间只有实现.
}
class Impl implements IA{// 实现接口也要实现里面的抽象方法.
       void m1(){}// 编译不通过
       publicvoid m1(){} // 这样才能编译通过,嘻嘻.
       publicvoid m2(){}// 这样才能编译通过,嘻嘻.
       }
abstractclass MyClass{
       publicvoid m6() {
       }
}
class Impl extends MyClass implements IC,ID{// 这样会绕过单继承的限制,而且可以继承多个接口.
       publicvoid m1(){} publicvoid m2(){}publicvoid m3(){}publicvoid m4(){}publicvoid m5(){}
       publicvoid m6(){}
}
class Sub extends Super{
       publicabstractvoid m1();publicabstractvoid m2();
}
class Super{
      
}
======================================================================
以下是老师的笔记:
static
属性 类变量 全类共有 类加载时创建,类名访问
 方法 类名调用,静态方法中不能访问类的非静态成员,可以覆盖,只能被静态方法覆盖,没有多态
 初始代码块 类加载时运行
 类加载:
 一个类编译之后会形成.class文件,储存了类的全部信息。当JVM第一次需要用到这个类的时候,会根据ClassPath找到这个.class文件,用输入流把文件中的信息读入JVM并保存起来,这样,JVM就“认识”了这个类
 类加载时机:第一次用这个类的时候
 1. 第一次创建类的对象,会加载
 2. 访问类的静态成员,会加载
 3. 声明类的引用,不会加载
 4. 加载子类,必然先加载父类
 5. 如果调用的是子类从父类中继承到的静态方法,只会加载父类
 6. 如果访问的是类的静态常量,如果在编译的时候能够确定这个常量的值,则运行时不会加载,否则,编译时无法确定常量值,那么运行时就会加载
 设计模式:单例模式
 用途:一个类只能有一个对象
 实现:会有一个静态的属性,就是该类的一个对象。提供一个静态方法,来获得这个唯一的静态属性(单例),同时构造方法私有    
final
 变量:常量,一旦赋值,不能改变,为属性常量赋值的时机:对于实例常量,初始化或者构造方法中可以赋值;对于类常量,初始化或者静态初始代码块中可以赋值
 方法:不能被覆盖
 类 :不能被继承
abstract
 方法:只有定义,没有实现
 类:不能构造对象,但可以用来声明一个引用(作为编译时类型)
 如果一个类有抽象方法,这个类必须是抽象类,如果一个类是抽象类,不一定有抽象方法
 子类继承一个抽象类,就必须覆盖(实现)父类(抽象类)中的所有抽象方法,否则,子类就也得是抽象类
 抽象类有构造方法
 通过abstract,我们可以把一个方法的定义放在父类,而留给子类实现。
接口
 一个接口是一个特殊的抽象类。所有的属性默认都是公开静态常量,所有的方法默认都是公开抽象方法
 接口之间可以多继承
 一个类在继承另外一个类的同时,还可以实现多个接口。而实现的每一个接口都将成为这个类的兼容类型,允许多态的使用
 一个类实现一个接口,如果这个类不是抽象类的话,那么就一定要实现接口中定义的所有方法
 接口没有构造方法
 接口的作用:
 1.实现多继承
   区分主类型和次要类型,接口的引入就使得我们可以对事物的共性作一个再抽象,抽象出副类型。
   这种多继承的关系不会破坏类之间单继承树状关系的复杂度
 2.标准
 标准的制定者、实现者、使用者分离
 解耦合的工具
 标准的使用者和标准的实现者通过接口实现弱耦合
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炼丹狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值