java面向对象

java面向对象

面向对象(OOP)

OOP: Object Oriented Programming

类是对一类事物的描述,是抽象的、概念上的定义

对象是实际存在的该类事物的每个个体,因而也称实例(instance)

在方法体外,类体内声明的变量称为成员变量。

在方法体内部声明的变量称为局部变量

成员变量:实例变量(不以static修饰),类变量(以static修饰)

局部变量:形参(方法、构造器中定义的变量),方法局部变量(在方法内定义),代码块局部变量(在代码块内定义)

局部变量除形参外,需显式初始化

static

静态代码块无法被调用 只加载一次 在JVM中永远只有一份 在方法区的常量池里 常量池里的东西永远只有一份
静态的东西是在class类加载时就在JVM中生成了
静态的只能访问静态的,非静态的可以访问静态的

使用范围:

在Java类中,可用static修饰属性、方法、代码块、内部类,但不能修饰构造器和局部变量

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

随着类的加载而加载

优先于对象存在

修饰的成员,被所有对象所共享(因为只有一份)

访问权限允许时,可不创建对象,直接被类调用

静态成员(除了静态属性),里面都是可以直接调用其他静态成员,不能直接调用普通成员

没有对象的实例时,可以用**类名.方法名()**的形式访问由static标记的类方法。

因为不需要实例就可以访问static方法,因此static方法内部不能有this。(也不能有super )

重载的方法需要同时为static的或者非static的。

初始化块

初始化块又称为代码块。属于类中的第四大成员。本质上是一个方法,它也有方法体,但没有方法名,没有参数,没有返回,而且也不是通过对象或类名显式调用,而是通过隐式调用

好处

1、和构造器很像,都是用于初始化信息

2、当多个构造器中有重复的语句,可以将这些重复的语句往上提取到初始化块中,提高代码的重用性

特点

1、静态初始化块的调用时机:加载类
  普通初始化块的调用时机:创建对象

2、静态初始化块只会调用一次,随着类的加载而加载,(类只加载一次)
  普通初始化块可以调用多次,随着对象的创建而加载

3、一个类中可以有多个静态初始化块和多个普通初始化块
静态初始化块的执行要早于普通初始化块
同一个类型的初始化块的执行顺序取决于定义的先后顺序!

4、一个类中如果有:静态初始化块、普通初始化块、普通属性初始化、静态属性初始化、构造器
执行顺序:
静态初始化块|静态属性初始化>普通初始化块|普通属性初始化>构造器

5、有父子类
执行顺序:
爷爷类的静态初始化块|静态属性初始化>
父类静态初始化块|静态属性初始化>
子类静态初始化块|静态属性初始化>
爷爷类普通初始化块|普通属性初始化>构造器>
父类普通初始化块|普通属性初始化>构造器>
子类普通初始化块|普通属性初始化>构造器

6、静态初始化块中遵循静态成员的特点,只能直接访问静态成员!

方法区 堆 栈

常量池:static final 里面的东西永远不能重复,只保存一份
new出来的对象都在堆里
对象的地址值在栈(取东西快)

栈:对象的引用、局部变量
堆:对象和全局变量(属性)
方法区:类信息,常量

可变参数的方法

概念:

jdk5.0出现的新特性。将同一个类中,多个方法名相同、参数类型相同、返回类型相同,仅仅是参数个数不同的方法抽取成一个方法,这种方法称为可变参数的方法

好处:
提高代码的重用性和维护性

语法:

	修饰符	返回类型	方法名(参数类型...参数名){
		
	}

注意:使用时,将可变长度的参数当做数组使用

使用特点:

	1、可变参数的实参可以为0个或任意多个
	2、可变参数的实参可以为一维数组类型
	3、可变参数和普通类型参数 一起使用时,只能放在最后
	4、一个参数列表中至多有一个可变参数!

方法重载与重写(覆盖)

方法重载:方法名相同,参数不一样

特点:

   ①、必须保证参数列表中至少有一样不同(参数类型、参数个数、参数顺序)
   ②、返回类型无要求
   ③、修饰符无要求

构造方法只能被构造方法调用 this.age=age this(); this(age);
封装的意义:不让别人调用自己私有的属性和方法
继承:抽象出共有的属性和方法,提高代码的复用性
子类继承父类时,先执行父类的构造方法,在执行子类的构造方法

方法覆盖(继承中子类覆盖父类的方法)

封装

好处
1、提高数据的安全性,隐藏细节
2、提高代码的重用性,有利于程序的扩展

广义的封装:方法、类、包
狭义的封装:类中的属性的封装

封装的具体体现

1、将属性私有化
2、提供公共的set方法,为属性赋值
3、提供公共的get方法,对外暴露该属性

规范

将所有的属性实现封装,当然如果有特殊要求
比如属性为只读,则仅仅提供get方法
比如属性为只写,则仅仅提供set方法

继承

好处

1、提高代码的重用性
2、提高代码的扩展性和维护性
3、为多态打下了基础

使用特点

1、子类到底继承了父类的哪些成员?
所有的属性和方法,只是私有的不能直接访问,而是通过公共的方法去访问
注意:子类在访问继承来的成员时,也是需要先去遵循访问权限的限定

2、子类不能继承父类的构造器,但必须调用父类的构造器

3、不能滥用继承,子类和父类之间必须满足 is-a的关系

4、子类可以直接继承一个父类,java中支持单继承!

5、子类的继承不限于直接父类

6、java中所有的类都直接或间接继承了Object类,也就是Object类为所有类的祖先类

子类调用父类构造器的特点

1、子类必须调用父类的构造器
2、子类如果没有显式的调用父类的构造器,则默认调用父类的无参构造器
   父类中如果没有无参构造器,则子类中必须显式的调用父类的有参构造器,通过super关键字去调用,语法为 super(实参列表);

3、构造器的调用,不限于直接父类

多态

多态性,在java中有两种体现:

1.方法的重载(overload)和重写(overwrite)。

2.对象的多态性 ——可以直接应用在抽象类和接口上

父类的引用指向子类的实例化对象

多态的体现

1、方法的多态性
方法的重写和重载

2、对象的多态性
对象的转型上!
Person p = new Student();

强制转换

强制转换(大的到小的 Dog dog=(Dog)animal 从父类到子类) 

向下转型:从父类到子类

语法:

子类类型 	引用名 =  (子类类型)父类引用;

特点:

①只能强转父类的引用,不能强转父类的对象
②要求父类的引用必须指向的是当前目标类型的对象
③可以调用子类类型中所有的成员

instanceof关键字,向下转型时使用

向上转型:从子类到父类,会自动转

父类的引用指向了子类的对象

public class Animal {
    private String name;
    
    public Animal() {
    }
    public Animal(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void eat()
    {
        System.out.println(this.name+"吃饭");
    }
    public void train1()
    {
        System.out.println("训练"+this.name);
    }
}



public class Dog extends Animal {
    public Dog() {
    }
	public Dog(String name) {
        super(name);
    }
    public void eat()
    {
        System.out.println(getName()+"吃骨头");
    }
    public void train1()
    {
        System.out.println(getName()+"跑的快");
    }
    //子类特有的的方法
    public void play()
    {
        System.out.println("狗玩飞盘");
    }
}



public class Cat extends Animal{
    public Cat() {
    }
    public Cat(String name) {
        super(name);
    }

    public void eat()
    {
        System.out.println(getName()+"吃鱼");
    }
    public void train1()
    {
        System.out.println(getName()+"跳的高");
    }

    //猫特有的方法
    public void play1()
    {
        System.out.println("猫抓老鼠");
    }
}


public class Women {
    //子类共有的方法
    public void feed(Animal animal)
    {
        animal.eat();
    }

    public void train(Animal animal)
    {
        animal.train1();
    }
     //强制转换(大的到小的 Dog dog=(Dog)animal)
    //向下转换 instanceof判断
    public void plays(Animal animal)
    {
        if(animal instanceof Dog)
        {
            Dog dog=(Dog)animal;
            dog.play();
        }
        else
        {
            Cat cat=(Cat)animal;
            cat.play1();
        }
    }
}


public class Test {
    public static void main(String[] args) {
        //多态
        Animal animal=new Dog("狗");
        new Women().feed(animal);
        new Women().train(animal);
        new Women().plays(animal);

        Animal animal1=new Cat("猫");
        new Women().feed(animal1);
        new Women().train(animal1);
        new Women().plays(animal1);
    }
}
java 中保留小数点后两位
		DecimalFormat decimalFormat = new DecimalFormat("0.00");
        String format = decimalFormat.format(11.99999);
        System.out.println(format);

在这里插入图片描述

equals与==

基本类型中,==比较的是内容

引用类型种,判断的是地址是否相等。

正常情况下,==和equals比较的都是地址值。

String类中equals比较的是内容,==比较的是地址值,因为String类中重写了equals方法,把原来比较地址的换为比较内容。

方法区中的内容只会出现一份

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Person p1 = new Person();
p1.name = "atguigu";

Person p2 = new Person();
p2.name = "atguigu";

System.out.println(p1.name .equals( p2.name));
//true p1.name比较的是字符串,重写了equals
System.out.println(p1.name == p2.name);//false new出来的
System.out.println(p1.name ==“atguigu”));//false 一个在堆里,一个在方法区里
String s1 = new String("bcde");

String s2 = new String("bcde");
System.out.println(s1.equals(s2));//true 重写了equals

int it = 65;
float fl = 65.0f;
System.out.println(6565.0f是否相等?” + (it == fl)); //true  基本类型中比较的是内容
char ch1 = ‘A’; char ch2 = 12;
System.out.println(65和‘A’是否相等?” + (it == ch1));//true
System.out.println(12和ch2是否相等?” + (12 == ch2));//true

String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("str1和str2是否相等?"+ (str1 == str2));//false
System.out.println(“str1是否equals str2?”+(str1.equals(str2)));//true

单例设计模式

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索。

​ 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的**构造方法的访问权限设置为private,**这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的

什么时候使用单例模式:
当一个项目中 要求某类只有一个对象时!
应用场景:
1、项目中只想多次调用该对象的方法时,为了提高效率
2、如果创建多个对象,会导致逻辑错误时

饿汉式

class Single{
 	//private的构造器,不能在类的外部创建该类的对象
     private Single() {} 
	 //私有的,只能在类的内部访问
     private static Single onlyone = new Single();
 	//getSingle()为static,不用创建对象即可访问
     public static Single getSingle() {
		return onlyone;
 	}
}
 public class TestSingle{
	public static void main(String args[]) {		
		Single  s1 = Single.getSingle();      //访问静态方法
		Single  s2 = Single.getSingle();
		if (s1==s2){
			System.out.println("s1 is equals to s2!");
		}}}

饿汉式上去就把对象私有化,new,并且设置为static,防止多线程产生的冲突。

懒汉式不是上去就把对象new好的,在返回方法的对象里创建了new的对象,存在多线程的问题。

饿汉式和懒汉式的差异:

1、创建对象的时机不同!

2、应用场合不同

如果仅仅考虑效率问题,可以使用懒汉式
如果考虑线程安全问题,可以使用饿汉式

Runtime类就使用了饿汉式单例设计模式

final

final关键字属于一种修饰符,可以用于修饰类、属性、方法、局部变量

特点

1、修饰类

如果用final修饰类,则该类变成了“太监类”,不能被继承
代表类:String、Integer等

2、修饰方法

如果用final修饰方法,则该方法不能被重写,但可以被继承

3、修饰属性和局部变量

①如果修饰变量(属性和局部),该变量就变成了常量,一旦赋值,将不能更改!(名称大写,且只能被赋值一次)

②修饰属性,需要注意以下事项:

	a、命名时最好遵循见名知义,且**纯大写**,提高代码的阅读性!
	b、一般来讲static和final往往一起搭配修饰常量属性
		两个修饰符的意思不冲突
		调用比较方便
		jvm对使用这两个修饰符搭配的属性,内部进行了优化

	c、常量属性在声明时或构造器时**必须初始化**

③基本类型的值,一旦更改,则就是更改值,不允许
引用类型的对象,如果更改属性值是允许的,但不能更改地址号!

static final:全局常量

获取时间

//获取时间戳 (方法一)
        long timeMillis = System.currentTimeMillis();
        System.out.println(timeMillis);
        //方法二
        Date date = new Date();
        long time = date.getTime();
        System.out.println(time);
        //把时间戳转换为时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String format1 = simpleDateFormat.format(timeMillis);
        System.out.println(format1);
        String format2 = simpleDateFormat.format(time);
        System.out.println(format2);

时间戳变为时间

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

String format=dateFormat.format(new Date(24667788000L));

时间变为时间戳

Date parse=dateFormat.parse("2020-04-08 02:21:21");

抽象类

将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

抽象类不能被实例化(不能new)。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。

不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法。

抽象(abstarct)的方法不用写具体的实现类,抽象方法必须写在抽象类里

特点:

 ①抽象类不能创建本类的对象
 ②抽象类有构造器,供子类调用
 ③抽象类中可以有哪些成员?
 任意成员(包含普通成员和抽象方法)
 ④抽象类中也可以没有抽象方法
 ⑤不能使用final修饰抽象类,因为和继承的意义相悖
 ⑥抽象类的扩展
 普通子类 继承抽象类要求必须实现里面所有抽象方法
 抽象子类继承抽象类不用实现里面的抽象方法

抽象方法的理解和特点

语法:

【访问修饰符】 abstract 返回类型 方法名(参数列表);

特点:

 	①没有方法体,只有方法签名,使用分号结尾
  
  	②修饰符不能是final、static或private中的任何一个
  因为这些修饰符和重写的意义相悖
  
  	③抽象方法只能出现在抽象类或接口中!

接口

接口(interface)是抽象方法和常量值的定义的集合。

从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。

一个类可以实现多个接口,接口也可以继承其它接口

接口的特点:

用interface来定义。

接口中的所有成员变量都默认是由public static final修饰的。

接口中的所有抽象方法都默认是由public abstract修饰的。

接口中没有构造器

接口采用多继承机制

实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类

接口的主要用途就是被实现类实现。(面向接口编程)

与继承关系类似,接口与实现类之间存在多态性

定义Java类的语法格式:先写extends,后写implements

接口也可以继承另一个接口,使用extends关键字

通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。

通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。

接口主要用来定义规范。解除耦合关系。

在这里插入图片描述

Java 1.8中,你可以为接口添加静态方法和默认方法

异常

finally中的代码,要想不执行,只能关闭程序

捕获异常的有关信息:

与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。

getMessage() 获取异常信息,返回字符串

printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

RuntimeException类或是它的子类,这些类的异常的特点是:

即使没有使用try和catch捕获,Java自己也能捕获(例:1/0),并且编译通过 ( 但运行时会发生异常使得程序运行终止 )。

如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则编译错误。也就是说,我们必须处理编译时异常,将异常进行捕捉,转化为运行时异常

重写方法不能抛出比被重写方法范围更大的异常类型。在多态的情况下,对methodA()方法的调用-异常的捕获按父类声明的异常处理。

用户自定义异常类

一般地,用户自定义异常类都是RuntimeException的子类。

自定义异常类通常需要编写几个重载的构造器。

自定义的异常通过throw抛出。

自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。

枚举类

JDK 1.5 新增的 enum 关键字用于定义枚举类

特点:

	1、使用enum关键字代替class关键字
	2、**对象(常量)的创建**必须放在枚举类中的第一句
	语法:
	对象名(实参列表),对象名(实参列表)**;**

	3、如果是无参构造,则无参构造的定义和实参列表都可以省略

若枚举只有一个对象, 则可以作为一种单例模式的实现方式

枚举类的属性是不可被更改的,一般枚举类中定义的属性,用大写字母表示

枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰

在这里插入图片描述

在这里插入图片描述

枚举类的主要方法:

**values()**方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。

转化为运行时异常

重写方法不能抛出比被重写方法范围更大的异常类型。在多态的情况下,对methodA()方法的调用-异常的捕获按父类声明的异常处理。

用户自定义异常类

一般地,用户自定义异常类都是RuntimeException的子类。

自定义异常类通常需要编写几个重载的构造器。

自定义的异常通过throw抛出。

自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。

枚举类

JDK 1.5 新增的 enum 关键字用于定义枚举类

特点:

	1、使用enum关键字代替class关键字
	2、**对象(常量)的创建**必须放在枚举类中的第一句
	语法:
	对象名(实参列表),对象名(实参列表)**;**

	3、如果是无参构造,则无参构造的定义和实参列表都可以省略

若枚举只有一个对象, 则可以作为一种单例模式的实现方式

枚举类的属性是不可被更改的,一般枚举类中定义的属性,用大写字母表示

枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰

枚举类的主要方法:

values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。

valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值