Java面向对象
初识面向对象
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是具体到微观操作,仍然需要面向过程的思路。
面向对象的本质:以类的方式组织代码,以对象的组织(封装)数据 ,从对象中抽象出类 。
面向对象方法
方法的定义:
方法的调用:
对象的创建分析
- 使用new关键字创建对象
- 使用new关键字创建的时候,会分配一些默认的值和空间,以及类中构造器(构造方法)的调用。
- 构造器也叫构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下特点:
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
面向对象三大特性
-
封装
高内聚,低耦合。类的内部数据操作细节自己完成,不允许外部干涉;仅暴露少量的方法给外部使用
属性私有:set/get
-
继承
继承的本质是对某一批类的抽象。extends,子类是父类的扩展。
继承是类和类之间的一种关系,初次之外类和类之间的关系还有依赖,组合,聚合等。
object类:
在Java中所有的类,都默认直接或者间接继承Object类。
super:
1. super调用父类的构造方法,必须在构造方法的第一个 2. super必须只能出现在子类的方法或者构造方法中 3. super和this不能同时调用构造方法 vs this: 代表的对象不同: this:本身调用者这个对象 super:代表父类对象的引用 前提 this:在没有继承的情况下也可以使用 super:只能在继承条件下才能使用 构造方法的区别 this();本类的构造 super();父类的构造
方法重写:
需要有继承关系,子类重写父类的方法; 1. 方法名必须相同; 2. 参数列表必须相同; 3. 修饰符:范围可以扩大但不能缩小 public > protected > default > private 4. 抛出异常:范围可以缩小,但不能扩大 ; ClassNotFoundException.--->Exception 重写子类的方法必须和父类一致;方法体不同。 为什么需要重写? 父类的功能子类不一定需要,过着不一定满足。
-
多态
·即同一种方法可以根据发送对象的不同采用多种不同的行为方式。 ·一个对象的实际类型是确定的,但可以指向对象的引用类型有很多 ·多态存在的条件 ·有继承关系 ·子类重写父类的方法 ·父类引用指向子类对象 注意:多态是方法的多态,属性没有多态性 instanceof X instanceof Y X:某类的对象引用 Y:某个类 使用instanceof操作符的表达式返回值为布尔值。如果返回值为true,说明X对象为Y的实例对象;如果返回值为false,说明X对象不是Y的实例对象。
抽象类和接口
抽象类:
-
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
-
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
-
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的。
-
抽象方法,只有方法的声明,没有方法的实现,他是用来让子类实现的。
-
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
接口:
-
普通类:只有具体实现
-
抽象类:具体实现和规范(抽象方法)都有
-
接口:只有规范
-
接口就是规范
-
接口的本质是契约,制定好了就需要遵守
-
OO的精髓是对对象的抽象,最能体现这一点的就是接口
作用:
- 约束
- 定义一些方法,让不同的人实现
- 方法都是public abstract
- 常量都是public static final
- 接口不能不能被实例化,接口中没有构造方法
- implements可以实现多个多个接口
- 实现类必须重写接口中的方法
内部类
内部类:
-
成员内部类
public class Outer { private int id = 10; public void out(){ System.out.println("这是一个外部类的方法"); } public class Inner{ public void in(){ System.out.println("这是一个内部类的方法"); } //获取私有属性ID public void getId(){ System.out.println(id); } } } //测试类 public class Application { public static void main(String[] args){ Outer outer = new Outer(); outer.out(); //通过外部类实例化内部类 Outer.Inner inner = outer.new Inner(); inner.in(); inner.getId(); } }
-
静态内部类
public static class Inner{ public void in(){ System.out.println("这是一个内部类的方法"); } //获取私有属性ID public void getId(){ System.out.println(id); } } //注意:在内部类前加上static会导致原先的getId报错,是因为在程序加载时,先加载加上static的Inner所以导致无法先实例化out就无法取出值。
-
局部内部类
public class Outer { //局部内部类 public void method(){ class Inner{ public void in(){ } } } }
-
匿名内部类
public class Test { public static void main(String[] args) { //没有名字初始化类,不能实例保存到变量中 new Apple().eat(); UserService uerService = new UerService(){ @Override public void hello(){ } }; } } class Apple{ public void eat(){ System.out.println("1"); } } interface UerService{ }