2.静态,单例,继承!

来源:互联网 发布:结构工程设计软件 编辑:程序博客网 时间:2024/05/22 15:10

 

一,代码块

1, 方法中的代码块

在方法中可以用{}的形式来定义一段代码,超出{}范围之后,{}中的变量就会自动销毁。

2, 类中的代码块

在类级别下用{}定义一段代码,它算是类的一个成员,当创建之后就会执行这段代码

静态的应用:

              每一个应用程序中都有共性的功能,可以将这些功能进行抽取,独立封装;

  ***被修饰成员具备以下特点:

              随着类的加载而加载;

              优先于对象存在;

              被所有对象所共享;

              可以直接被类名调用;

       静态缺点:

              生命周期过长,占用内存;且静态方法只能访问静态,访问出现局限性

       使用注意:

静态方法只能访问静态成员,非静态成员既可以访问非静态成员,也可以访问静态成员;

静态方法中不可以写thissuper关键字;

主函数是静态函数;

静态存在于方法区;

       Public static void mainString[] args

其中,public:代表着该函数的访问权限是最大的;

        Static:代表主函数随着类的加载就已经存在了;

        Void:主函数没有具体返回值;

        Main:不是关键字,是特殊的单词,被jvm识别;

String[] args):函数的参数列表;参数类型是一个数组,该数组中的元素是字符串。

实例变量和类变量的区别:

String name;//成员变量(实例变量)。

              static String country = "CN";//静态的成员变量(类变量)。

1,存放位置不同;

                       i.             类变量随着类的加载存在方法区中;

                     ii.             实例变量随着对象的加载而存在堆内存中;

       2,生命周期不同;

              类变量生命周期最长,随着类的消失而消失;

              实例变量随着对象的消失而消失;

二,静态变量

1, 什么是静态变量:

static修饰的变量就是静态变量,静态变量在类加载后就开始初始化,不用创建对象,可以直接使用;

静态变量可以使用“类名.变量名”进行访问,也可以使用“对象.变量名”进行访问,推荐使用前者;

静态变量被该类的所有对象所共享,就是该类所有对象都拥有这个变量;

2, 什么时候使用静态变量

当某个类所有对象都要使用一个数据时,这个数据就应该是静态的

 

三,静态方法

1, 什么是静态方法

静态方法可以在类加载后直接调用,不需要创建对象;

静态方法可以使用“类名.变量名”的形式进行访问,也可以使用“对象.变量名”的形式进行访问,推荐使用前者;

静态方法不能访问非静态成员,只能使用静态成员变量;因为非静态成员必须创建对象才能调用,而静态方法不需要创建对象就可以调用;

2, 什么时候使用静态方法

在定义方法时,如果这个方法不访问非静态成员,就可以定义为静态方法,这样别人使用方法时,无需创建对象,给调用者提供方便;

一个类无法创建对象时,通过静态方法获取对象;

四,静态代码块

1, 什么是静态代码块

静态代码块在类加载就执行;

静态代码块和静态方法相同,都是静态上下文不能访问外部非静态成员;

格式:

Static {

       静态代码块中的执行语句;

}

特点:

       随着类的加载而执行,只执行一次(类再次创建时不会执行),并优先于主函数;

       用于给类进行初始化;

2, 什么时候使用静态代码块

在定义一个类的时候,如果希望别人一使用这个类,就执行一段代码,那么我们就把这段代码定义成静态代码块

 

//练习静态,静态代码块,说出打印结果;

classStaticBlock {

//静态代码块随着类的加载而执行,只执行一次,并优先于主函数;

static {

       System.out.println("静态"); 

}

public static void main(String[] args) {

       //newPeople().fun();

       Peoplep1= new People();

       p1.fun();

       Peoplep2 = new People();

       p2.fun();

}    

}

 

class People {

static {

              System.out.println("静态代码块");     

}

//成员代码块有对象建立就运行一次;

{

              System.out.println("成员代码块");     

}

//构造函数,创建people()对象就执行一次;

public People() {

              System.out.println("构造函数"); 

       }    

public static void fun() {

       System.out.println("fun()"); 

}

}

 

//练习:打印顺序-----打印结果是B C A D

class Test7 {

public static void main(String[] args) {

       newA(123);

       //newA();

}

}

class A {

B b = new B();

{

       b =new B(123);    

}

public A() {

//给成员变量赋值,执行代码块

       System.out.println("A");      

}    

public A(int x) {

       this();//创建Aint x)对象;访问无参构造函数A();

       System.out.println("D");      

}

}

class B {

public B() {

       System.out.println("B");      

}    

public B(int i) {

       System.out.println("C");      

}

}

五,单例设计模式;

       设计模式:解决某类问题最行之有效的方法;java中有23种设计模式;

       单例设计模式:解决一个类在内存中只存在一个对象;

       当需要将事物的对象保证在内存中唯一时,就将使用单例设计模式,

例如:

       classSingleDemo {

              public static void main(String[] args) {

//创建对象s1 ,s2

                     Singles1 = new Single();

                     Singles2 = new Single();

                     System.out.println(single1);

System.out.println(single1);

}

}

       ClassSun {

              private static Sun sun = new Sun();            

// 2. 类内部创建一个对象,使用成员变量引用.static修饰在类加载后初始化.防止类外修改加上private

      

       privateSun() {                                                

// 1. 私有化构造函数,阻止类外创建对象

       }

      

       publicstatic Sun getSun() {                

// 3. 提供一个get方法获取对象,为了让类外直接使用加上static

              return sun;     

       }

      

       //...

      

       //...

}

}

,函数的参数传递:

       1,基本数据类型:

基本数据类型直接存储在变量中,在调用函数的时候,函数中的实参也将记录住实参数据,函数中对形参改变,原调出的数据不变;

2, 引用数据类型

引用数据类型的变量中存储的是地址,在调用函数时,传递的也是地址,

在函数中通过地址改变对象上的内容,调用出也会一起改变,因为引用的都是一个地址

七,继承:

1, 什么是继承

a)        一个类使用extends关键字可以继承另一个类

b)       写法:class子类名extends 父类名 {}

c)        子类会继承到父类的属性和方法;

2, 什么时候使用继承;

a)        在定义一个类的时候,发现另一个类的功能这个类都需要,那么我们就可以再当前类名的后面使用extends关键字来继承另一个类

3, 多继承问题

Java中只支持单继承,类不能多继承(接口可以多继承),可以多重继承;因为一个类如果继承多个父类,如果父类中有相同的方法声明,子类就无法确定选用哪一个了

4, 继承的原理

子类之所以继承到父类的属性和方法,其实是在创建子类对象的时候也创建了一个父类对象;

访问子类的属性和方法时会先在子类中查找,找到就直接使用,找不到会使用父类的

5, superthis区别:

super是调用父类构造函数,this是调用当前类构造函数;

它们都是只能出现在构造函数的第一句,二者不能同时使用,只能选择其一;

构造函数的第一句要么是this,要么是super,如果没写,默认是super

练习:写出输出语句;------A E B D C F H G

class Test8 {

public static void main(String[] args) {

       newB();         //AE BDC FHG

}    

}

class A {

static {

       System.out.println("A");      

}

{

       System.out.println("B");

}

A() {     

       this(123);

       System.out.println("C");

}    

A(int i) {

       System.out.println("D");

}

}

class B extendsA {

static {

       System.out.println("E");

}

{

       System.out.println("F");

}

B() {

       this(123);

       System.out.println("G");

}

B(int i) {

       System.out.println("H");

}

}

继承出现后,代码上也有一些特点:

       1,变量。

              当子父类中定义了相同的名称的成员变量,

              子类要使用父类中的同名变量时,需要使用关键字super来区分。

              一般不会出现这种情况,因为父类中有了,子类不需要定义。

              而且父类定义时,一般变量都私有化。

 

       2,函数。

              子类可以直接访问父类中非私有的成员函数。

              特殊情况:当子类中定义了与父类一模一样的方法时,会发生覆盖操作。大多指的是非静态方法。

                             最终会运行子类的方法,父类相当于被覆盖了。

                             函数的另一个特性:覆盖(重写,复写)。

                             什么时候用啊?

                             当父类的功能要被修改时,不建议修改源码。

                             只要通过一个类继承原有类,定义一个新的升级后的功能即可。

                             但是功能是相同的,只是实现方法改变。这是子类可以沿袭父类中的功能定义,

                             并重写功能内容。这就是覆盖。

 

                             覆盖注意事项:

                              1,子类覆盖父类时,必须权限要大于等于父类权限。

                              2,静态不能覆盖非静态。

                    

       3,构造函数。

              构造函数可以本类进行对象初始化,也可以给子类对象进行初始化。

             

为什么子类一定要访问父类中的构造函数。

 

因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。

所以子类在对象初始化时,要先访问一下父类中的构造函数。

如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

7. 子类的实例化过程。

子类的所有的构造函数,默认都会访问父类中空参数的构造函数。

因为子类每一个构造函数内的第一行都有一句隐式super();

 

当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。

 

当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。

子类中至少会有一个构造函数会访问父类中的构造函数。

原创粉丝点击