【java基础】06 面向对象编程(下)

目录

6.1 关键字static

1 作用

2 static关键字使用

3 使用static修饰属性

4 使用static修饰方法

应用:单例设计模式

1 概念

2 实现

3 区分懒汉式与饿汉式

4 单例设计模式优点

5 应用

6.2 理解main方法语法

1 使用说明

6.3 类的成员之四:代码块

1 作用

2 修饰

6.4 final关键字

1 修饰的结构:类、方法、变量

2 修饰类

3 修饰方法

4 修饰变量

6.5 抽象类与抽象方法

1 abstract关键字使用

2 修饰类:抽象类

3 修饰方法

4 应用

5 注意点

6 抽象类的匿名子类

多态的应用:模板方法设计模式

6.6 接口

1 作用

2 使用

3 如何定义接口:接口中的成员


6.1 关键字static

1 作用

当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上 的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象, 其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少 对象的情况下, 某些特定的数据在内存空间里只有一份, 例如所有的中国人都有个 国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中 都单独分配一个用于代表国家名称的变量。
static修饰的变量或方法不属于某一个类所有。

2 static关键字使用

static:静态的
static可以用来修饰:属性、方法、代码块、内部类

3 使用static修饰属性

静态变量、类变量
属性分为 静态属性(static)非静态属性(实例变量)
实例变量:我们创建了多个类的对象,每个对象都独立拥有一套类中的非静态属性。当修改一个对象的非静态属性时,不会导致其他对象非静态属性值修改。
静态变量:我们创建了多个类的对象,共享一个静态变量。当修改一个对象的静态变量时,其他对象调用此变量,是修改过的。
其他说明:
  • 静态变量随着类的加载而加载(实例变量随着对象的创建而创建),静态变量加载早于对象创建。
  • 由于类只加载一次,静态变量在内存中只存在一份, 存在 方法区 静态域 中。 
  •                类变量        实例变量
             类            yes                no
           对象           yes               yes

静态属性举例:

System.out :out为System类的静态属性
class Chinese{
    String name;
    static String nation;
}
//测试
Chinese c1 = new Chinese();
c1.name = '张三';
c2.nation = 'CHN';
Chinese c2 = new Chinese();
c2.name = '李四';
sysout(c2.nation); //此时c2的nation有值,为'CHN'

4 使用static修饰方法

  • 使用与属性相似。
  • 静态方法中,只能调用静态的方法和属性;非静态方法中,可以调用静态的方法和属性。
  • 静态方法中不能使用this和super关键字。(生命周期不够,关于静态属性和方法的使用,大都从生命周期角度解释)
开发中,如何确定一个属性是否声明为static的?
  • 属性可以被多个对象共享,不会随着对象的不同而不同。
  • 类中的常量也常常被修饰为static。
开发中,如何确定一个方法是否声明为static的?
  • 操作静态属性的方法通常设置为静态。
  • 工具类中的方法,习惯声明为static。如:Math、Arrays、Collections。
举例:
class Circle{
    private double r;//圆的半径
    private static int total; //记录第几个对象(多个对象共有的,需要声明为静态的)
    
    public Circle() {
        total++;
    }

    public Circle(){
        this();
        this.r = r;
    }

    public static int getTotal() { //注意方法为静态的
        return total;
    }
    public static void setTotal(int total) {
        Circle.total = total;
    }
}

应用:单例设计模式

1 概念

设计模式:设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、 以及解决问题的思考方式。
单例设计模式:就是采取一定的方法保证在整个的软件系统中, 某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。 如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构 造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生 类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无 法得到类的对象, 只能调用该类的某个静态方法以返回类内部创建的对象 , 静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象 的变量也必须定义成静态的。

2 实现

1. 饿汉式:
2. 懒汉式:懒汉式暂时还存在线 程安全问题,讲到多 线程时,可修复

3 区分懒汉式与饿汉式

饿汉式:
好处:是线程安全的。
坏处:对象加载时间过长。
懒汉式:
好处:延迟对象的创建。
坏处:目前的写法是线程不安全的。(线程1在进行到判断与new之前时,线程二判断对象还是null,会创造两个对象)

4 单例设计模式优点

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的 产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可 以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方 式来解决。

5 应用

  • 网站的计数器,一般也是单例模式实现,否则难以同步。
  • 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志 文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  • 据库 连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库 资源。
  • 项目中, 读取配置文件的类,一般也只有一个对象。没有必要每次使用配置 文件数据,都生成一个对象去读取。
  • Application 也是单例的典型应用
  • Windows的Task Manager ( 任务管理器)就是很典型的单例模式
  • Windows的Recycle Bin ( 回收站)也是典型的单例应用。在整个系统运行过程 中,回收站一直维护着仅有的一个实例。

6.2 理解main方法语法

1 使用说明

  • main()作为程序入口。
  • main()也是一个普通的静态方法。
  • main()可以作为我们与控制台交互的方式。(之前:使用Scanner)
public class Test {
    public static void main(String[] args) {
        for(int i = 0; i < args.length; i++) {
            System.out.println("***"+args[i]);
        }
    }
}
在eclipse中交互:右键 -> run as -> java application(先编译) -> Run As ->run configurations -> 找到编译过的文件 ->arguments中输入参数
控制台交互:java name data1 data2 data3 ...

6.3 类的成员之四:代码块

1 作用

初始化类或对象。

2 修饰

如果有修饰的话,只能使用static修饰。可以分成 静态代码块非静态代码块
继承情况下的执行顺序:(由父及子,静态先行)
父类的静态代码块 ->  子类的静态代码块 ->  父类的非静态代码块 ->  父类的构造器 ->  子类的非静态代码块 ->  子类的构造器
属性赋值的顺序:
默认初始化 -> 显式初始化/代码块赋值(取决于谁先写) -> 构造器初始化-> 有对象以后调用对象.属性或对象.方法赋值。

6.4 final关键字

1 修饰的结构:类、方法、变量

2 修饰类

final修饰的类不能被继承。String, System, StringBuffer

3 修饰方法

final修饰的方法不能被重写。Object中的getClass();

4 修饰变量

final修饰为常量。
final修饰属性:可以考虑采用显式初始化、代码块初始化、构造器初始化(定义多个构造器,则每个构造器都需要赋值一次)
                        简单的赋值,并且所有对象值相同,可采用显式初始化;复杂的赋值需要代码块;每个对象值各不相同可以使用构造器初始化。
final修饰局部变量:尤其是修饰形参时,调用此方法时赋值,赋值以后只能使用不能修改。
static final:修饰属性:全局常量
                    修饰方法:一般不常用
举例:
public class Something {
    public static void main(String[] args) {
        Other o = new Other();
        new Something().addOne(o);
    }
    public void addOne(final Other o) {
        // o = new Other(); //报错
        o.i++; //不会报错,o不可以修改,但是o中的属性可以修改
    }
}
class Other {
    public int i;
}

6.5 抽象类与抽象方法

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一 般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父 类设计得非常抽象,以至于它没有具体的实例,这样的类叫做 抽象类

1 abstract关键字使用

abstract:抽象的
可以用来修饰的结构:类、方法

2 修饰类:抽象类

abstract class Person{
}
  • 此类不能实例化。
  • 类中仍然提供构造器,便于子类对象实例化时调用。
  • 开发中,都会提供子类,让子类对象实例化。

3 修饰方法

public abstract void method();
  • 只有方法的声明,没有方法体。
  • 包含抽象方法的类,一定是抽象类。反之,抽象类中可以没有抽象方法。
  • 若子类重写了父类中的抽象方法之后,子类方可实例化。否则,子类为抽象类,需要用abstract修饰。

4 应用

抽象类是用来模型化那些父类无法确定全部实现,而是由其子类提 供具体实现的对象的类。

5 注意点

  1. abstract不能用来修饰:属性、构造器等结构。
  2. 不能用来修饰私有方法、静态方法、final方法、final类。

6 抽象类的匿名子类

public class Test {
    public static void main(String[] args) {
        Worker worker = new Worker();
        method(worker);//非匿名类非匿名对象
        method(new Worker());//非匿名类匿名对象
        //创建了匿名子类对象p,(省事,不用特意在造一个子类)
        Person p = new Person() {
            @Override
            public void eat() {
                
            }           
        };
    }
    public static void method(Person p) {
        p.eat();
    }
}
abstract class Person{
    public abstract void eat();
}
class Worker extends Person{
    public void eat() {
        
    }
}

多态的应用:模板方法设计模式

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模 板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象 类的行为方式。
解决的问题:
  1. 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以 把不确定的部分暴露出去,让子类去实现。
  2. 换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用, 这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽 象出来,供不同子类实现。这就是一种模板模式。
举例:
public class Test {
    public static void main(String[] args) {
        SubTemplate t = new SubTemplate();
        t.spendTime();
    }
}
abstract class Template{
    //计算某段代码计算花费时间
    public void spendTime() {
        long start = System.currentTimeMillis();
        code();
        long end = System.currentTimeMillis();
        System.out.println("花费的时间为:" +  (end - start));
    }
    
    public abstract void code();
}
class SubTemplate extends Template{
    public void code() {
        //要测试的代码体     
    }
}

6.6 接口

1 作用

  • 有时必须从几个类中派生出一个子类,继承它们所有的属性和方 法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
  • 有时必须从几个类中抽取出一些共同的行为特征,而它们之间又 没有is-a的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打 印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都 支持USB连接。

2 使用

  • 使用interface定义。
  • java中,接口和类是并列的两个结构

3 如何定义接口:接口中的成员

jdk7及以前:只能定义全局常量(public static final) 和抽象方法(public abstract)
interface Flyable{
    public static final int MAX_SPEED = 7900; //public static final可以省略掉,默认为静态常量

    public abstract void fly(); //public abstract可以省略掉

}
注:
  1. 接口不能定义构造器,意味着接口不能实例化。
  2. 接口同通过让类实现的方式使用。如果实现类覆盖了接口左右抽象方法,就可以实例化。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值