面向对象

来源:互联网 发布:淘宝闲置物品怎么下架 编辑:程序博客网 时间:2024/06/09 23:00


jvm内存管理

每个java虚拟机实例都有一个方法区及一个堆区,由该实例中所有线程共享。虚拟机装载class文件时,把解析的类型信息放入方法区;
程序运行时,把创建的对象放入堆区。每个新线程被创建时,都会得到一个PC寄存器和一个Java栈。PC寄存器指示下一条将被执行的
Java指令,Java栈存储该线程中Java方法调用的状态,包括局部变量、参数、返回值、运算的中间结果等
方法区:类加载时存放类的类型信息,包括类型字段的信息(字段名、字段类型、字段的修饰符、字段在类中定义的顺序)、 静态变量
                和方法信息,方法信息中包含类所有方法的字节码
堆区:存放对象,其中包括类及其父类的非静态变量
栈区:一个线程有一个栈,可能有多个方法一个正在运行的方法占一个栈帧,会在栈中存储局部变量等对象初始化及调用方法过程:
继承方法的特点

成员方法:1、子类覆盖父类,权限必须大于父类权限
                    2、静态只能覆盖静态
重载:同名函数的参数列表不同
重写:子类和父类方法要一模一样
构造方法:实际就是必须先调用父类构造方法初始化父类
                    类都有一个默认的空参数构造方法,一旦显式定义构造方法该方法就不存在
                    子类对象初始化时,父类构造函数也会运行,每一行都有隐式的super();
                     当父类没有空参数的构造方法时,子类必须用super()显示调用父类有参数的构造方法,且在第一行
                     因为子类可以直接使用父类的变量,所以需要初始化
                     子类的构造函数也可以通过this()来访问本类的构造函数,但子类中至少有一个构造函数调用父类

           class Farther{int x = 1;Farther(int x){this.x = x;}   }   class Son extends Farther{Son(){super(3);//父类中只有有参的构造方法,使用super()将报错,显式调用有参,且必须在第一行}Son(int x){this();//this也只能在第一行,但必须有一个构造方法调用了父类,实际上也是先初始化父类this.x = x;}
多态

体现为父类引用指向子类的对象,Java编译器按照引用变量所声明的类型处理,运行时根据引用的对象动态绑定
成员函数:编译时期:参阅引用类型变量所属的类中是否有调用的方法,如果有,编译通过。否则失败
运行时期:参阅对象所属的类中是否有调用方法
成员变量:无论编译和运行都参考左边(引用类型所属的类)
静态成员函数:无论编译和运行都参考左边

        class Fu{int num = 1;public void method1(){System.out.println("Fu_method_1");}public static void method2(){System.out.println("Fu_method_2");}}class zi extends Fu{int num = 2;//覆盖父类的同名变量public void method1(){//覆盖父类的方法System.out.println("Zi_method_1");}public static void method2(){System.out.println("Zi_method_2");}public void method3(){//定义子类特有的方法System.out.println("Zi_method_3");}}class Demo{public static void main(String[] args){Fu f= new Zi();//向上转型System.out.println(f.num);//打印父类的值1f.method1();//打印Zi_method_1f.method2();//打印Fu_method_2//instanceof判断一个引用类型所引用的对象是否是一个类的实例//一个类的实例包括类本身的实例,以及具有继承或者实现关系的类的实例if(f instanceOf Zi){((Zi)f).method3();//向下转型,method3是子类特有的方法}}}

抽象类与接口的异同
接口中的变量默认为public static final(可以省略但必须显式的初始化),方法声明为public abstract
相同:1、都代表系统的抽象层
            2、都不能被实例化
            3、都包含抽象方法
区别:1、抽象类可以有具体的实现,提高代码的重用性,接口只能包含抽象方法
             2、一个类只能继承一个抽象类,可以实现多个接口
==和equals的区别
1、"=="是操作符,比较两个操作值是否相等,既可以是基本数据类型,也可以是引用类型,
       当是引用类型是,必须是同一个对象,即同一个内存地址
       "=="比较引用变量时,两个变量被声明的对象必须相同,或者具有继承关系   new Cat()==new Dog();//编译错误因为没有意义
2、equals方法继承自Object类,比较两个对象是否相等(Object类中的此方法调用了"==""操作符),
      大多数类重载了此方法,如String类

                Integer a = new Integer(100);//200时,判断有变化Integer b = 100;//根据JDK1.5新特性,自动装箱,相当于Integer b = new Integer(100);Integer c = 100;int d = 100;System.out.println(a==b);//打印false,a和b是两个对象引用,内存地址不同System.out.println(a.equals(b));//打印true,Integer对象重载了equals()方法,比较数值的大小是否相等System.out.println(a==c);//打印false,原因同b一样System.out.println(a.equals(c));//打印trueSystem.out.println(b==c);//<span style="color:#ff6666;">打印true,为了提高内存的利用率,对一个字节以内的值,相同的值只存放一次,常量池</span>System.out.println(b.equals(c));//打印true的原因是重载System.out.println(a==d);//打印true,自动拆箱,比较的是数值System.out.println(a.equals(d));//打印true,自动装箱,把d封装成Integer对象,equals比较实际的数值大小System.out.println(b==d);//打印true,自动拆箱,比较数值是否相等System.out.println(b.equals(d));//打印true,自动装箱,把d封装成Integer对象,equals比较实际的数值大小
内部类及访问规则
实例内部类:1、实例内部类自动持有外部类的实例引用,可以访问外部类的所有成员变量和成员方法
                        2、实例内部类不能定义静态成员和静态方法
                        3、具有和外部类同名的变量时,访问外部类成员变量Outer.this.xx,访问内部类成员this.xx,访问局部变量xx
静态内部类:1、可以直接访问外部类的静态成员,访问非静态成员必须通过外部类的实例
                         2、内部可以定义实例成员变量,但不能定义非静态的成员方法
                         3、客户端可以通过类名直接访问静态内部类的静态成员,如Demo.Inner2.show();
局部内部类:1、局部内部类不能有访问控制修饰符和static修饰符
                         2、局部内部类内部不能有静态成员
                         3、访问所在方法的局部变量,该变量必须是final类型的参数和变量
class Demo{      int x =1;      static int y = 2;      private Inner1 inner = new Inner1();//外部类可以直接使用内部类      class Inner1{    int x = 5;    public void show(){ int x = 6;System.out.println(x);//使用局部的变量x,打印6System.out.println(this.x);//使用内部类的成员变量x,打印5System.out.println(Demo.this.x);//使用外部类的成员变量x,打印1(没有同名变量时可以省略)    }       }       static class Inner2{      static int m;      int n;//静态内部类可以拥有非静态成员变量      public static void show(){     System.out.println(y);//只能访问外部类的静态成员     System.out.println(new Demo().x);//通过外部类的实例访问非静态成员      }       }       public void show(){     final int n=0;     class Inner3{//定义局部内部类,在方法中public void show(){System.out.println(n);//访问本方法中的局部变量,该变量必须是final类型System.out.println(x);//访问外部类的成员变量}      }Inner3 n3 = new Inner3();//创建内部类对象,必须先定义再创建n3.show();       }       public static void main(String[] args){      Demo.Inner1 n1= new Demo().new Inner1();//创建成员内部类实例必须先创建外部类对象      n1.show();      Demo.Inner2 n2=new Demo.Inner2();      n2.show2();      Demo.Inner2.show();//直接调用静态内部类的静态方法      Demo d = new Demo();      d.show();//调用成员方法,内部有局部内部类的对象       }             }
static和final关键字
         1、静态变量:随着类的加载而加载,先于对象存在,存在与方法区,只有一份被所有该类的实例共享,通过类名调用
         2、静态函数:只能访问类中的静态变量,类中不能使用this和super,不能是抽象方法
         3、静态代码块:类加载时只执行一次,不同的静态代码块按顺序依次执行
     class Demo{static int x = 1;static{//静态代码块。类加载时执行一次x=x+1;System.out.println("a "+x);}static{//后于上一个静态代码块执行x=x+1;System.out.println("b "+x);}{//<span style="color:#ff6666;"><strong>构造代码块。每创建一个新对象的时候执行,先于构造函数,后于静态代码块执行</strong></span>this.x = this.x+1;System.out.println("c "+x);}Demo(int x){//构造函数,访问被所有实例共享的静态变量this.x = x;System.out.println("d "+x);}public static void main(String[] args){Demo demo = null;//<span style="color:#ff6666;"><strong>定义一个引用时并没有加载对应的类,只有具体使用的时候才加载,如:创建其对象,调用静态方法等</strong></span>demo = new Demo(7);//打印:a 2 b 3 c 4 d 7demo = new Demo(8);//c 8 d 9}}
1、final修饰的类不能被继承
2、final修饰的方法不能被子类覆盖,private类型的方法默认是final的
3、final类型的变量之能被赋值一次,包括成员变量和局部变量,修饰成员变量时必须被显式的初始化
    class Demo{int y;//默认初始化值0,不必显式初始化final int x ;//只有这一句编译报错,显式初始化包括直接赋值,构造函数赋值,构造代码块赋值/* final int x = 1;   {     //通过构造代码块初始化x=1;   }   Demo(int x){this.x = x;}//通过构造函数初始化*/}
单例设计模式:一个类在内存中只存在一个对象
              1、将构造函数私有化
               2、在类中创建一个本类对象
               3、提供一个方法获取该对象
饿汉式(推荐):class Demo{private Demo(){}//私有构造函数private static Demo d = new Demo();//创建一个对象,static是因为调用方法是静态的public static Demo getInstance(){ return d;}//静态方法使用类名调用,返回实例对象}懒汉式:<strong>实例延时加载,多线程访问存在安全问题,使用同步代码块,为提高效率使用双重判断,使用的锁是该类所属的字节码文件对象</strong>class Demo{private Demo(){}private static Demo d = null;public static  Demo getInstance(){if(d==null){//--A线程等待锁,B释放后d!=null,假如不判断两次,又创建一个对象synchronized(Demo.class){//静态函数同步使用字节码文件的对象if(d==null)d = new Demo();//延时加载}}return d;}}
模板方法设计模式
                        在定义功能时,功能的一部分是确定的,但有一部分是不确定的,而确定的部分在使用不确定的部分,那么就将不确定的部分暴露出去,由该类的子类去完成

             class ClassLoader{//子类继承此类protected  /*final*/ Class loadClass(){//不一定定义为final,确定的方法findClass();//由子类覆盖的方法}protected /*abstract*/ class findClass(){//不确定的方法去子类复写,也可以提供默认的实现方式}}
访问控制修饰符、package和jar
public:全部的类protected:本类、同一个包中的类、不同包中该类的子类(一般把某个变量或者方法用protected修饰,  就是为了供其子类使用,因为程序都不一定在一个包中)default:本类和同一个包中的类private:只有本类自身可以访问自动建包使用参数-d指定目录:javac -d . xxx.java访问类需要使用 包名.类名切换到包所在目录下后:jar -cf Demo.jar packa packb:-c说明创建新jar -f指定jar名 不同的包用空格分隔jar -tf Demo.jar 查看jar包中的文件jar -cvf Demo.jar 打印详细信息jar -cvf Demo.jar >c:\demo.txt 将控制台信息输出到demo.txt中使用jar包中的class文件,将其放到classpath目录下

原创粉丝点击