本文详细介绍了Java中的面向对象特性,包括封装的概念与案例、单例模式、继承原理及其用法、方法重写规则、super关键字的作用以及抽象类和抽象方法的运用。
前言:本篇文章会介绍Java语言面向对象的三大特征中的封装与继承(多态会在(四)中介绍)
封装
概念:
将类中的某些信息,使用不同的访问权限修饰符隐藏起来,不让外界直接访问操作,而是通过类 中向外提供的特定方法访问,方便加入控制语句,主动权在类手中
案例:
封装案例1:将类中成员变量私有化
public class Student { private String name; private int age ; }
此时在其他类中不能任意访问成员变量,只能通过类中提供的特殊的方法进行访问
public String getName() { return name; } public void setName(String name) { //加入控制语句 if(name.length()>1&&name.length()<5);{ this.name = name; } } public int getAge() { return age; } public void setAge(int age) { //加入控制语句 if(age<100&&age>0){ this.age = age; } }
让我们来测试下吧:
public static void main(String[] args) { Student s1 = new Student(); s1.setName("小王"); //符合setName方法中的条件 s1.setAge(-1); //不符合setAge方法中的条件 System.out.println(s1.getName()); System.out.println(s1.getAge()); }
在IDEA中可以通过右键方法变量,选择Generate,点击setter或者getter,直接创建一个外部可用的方法,这样就可以减少我们手写方法的时间了.
(按住Ctrl键可多选)
(这样就可以快速生成向外提供的特殊方了)
封装案例2:将类中的方法私有化
单例模式:让一个类在一个程序中只能创建一个对象,将类的构造方法私有化,外界不能随便用.
public class Window { //在类加载时,只创建了一个唯一对象 static Window window = new Window(); //将构造方法私有化,在外界不能随意调用 private Window(){ } //向外界提供可获得此对象的方法 public static Window getWindow(){ return window; } public static void main(String[] args) { System.out.println(Window.getWindow()); System.out.println(Window.getWindow()); System.out.println(Window.getWindow()); } }
可以看到,此例中创建的每个window的哈希值都相同于Window类中第一次创建的window
作用:可以有效的避免创建多个对象,达到在一个程序中只创建一个对象的作用
继承
概念:将同一类事物中共性的属性和行为进行抽取,定义为一个类中(基类),其他类可以继承 基类,就可以拥有基类中的功能,但不能使用基类中私有的内容.
作用:实现代码的复用性,以及可以在子类扩展自己特有的功能,而不影响其他类.(优点)
使用条件: 只要符合is-a关系(什么是什么关系,比如苹果是水果),就可以使用继承,一个类只能直接继承一个类,而间接的可以继承多个类,称为继承的传递性,例如b继承a,然后c继承b,则c也继承了a.
注意:当一个类没有显示继承其他类的时候默认继承object类,Object类是java类体系中最大的类,Object类之上再也没有别的类
继承的基本语法:
在创建类的时候在类名后使用extends关键字继承别的类,子类继承父类后,拥有了父类的成员变量和成员方法,但不能访问私有成员。
public class Cat extends Animal{ //Cat继承Animal的成员变量和成员方法,但不能访问私有成员 }
方法的重写
概念:
当父类中方法的实现不能满足子类需求时,可以在子类中对父类的方法进行重写(覆盖),这样调用时,就会调用子类中重写的方法。
重写时需要注意:
1.子类重写的方法结构与父类方法的结果必须一致(方法名,参数列表,返回值类型必须一致)
2.子类重写的方法使用的访问权限不能小于父类被重写方法的访问权。
3.构造方法,静态方法不能重写,成员变量不存在重写
4.使用 @Override 注解标签
关于@Override注解标签:
@Override是Java中的一个注解标签,定义在重写的方法上面,表示此方法是从父类重写而来,也可以不用添加,不过建议保留,因为编译器可以进行语法验证 ,并且阅读代码时可以明确的知道此方法是重写的。
快速生成重写方法:
在IDEA中可以通过在子类括号内部的空白中右键空白处选择Generate,点击Override Mathod
super关键字
作用:在子类中用来调用父类中的成员,super可用于访问父类中定义的属性,可调用父类中定义的成员方法,还可以在子类构造器中调用父类的构造器;当子父类出现同名成员时,可以用super表明调用的是父类中的成员。
super和this区别:
this代表本类对象的引用,表示当前对象.
super代表父类的内存空间的标识,调用的是父类中成员,不是父类对象.
继承中的构造方法
概念:子类继承父类时,不会继承父类的构造方法,只能通过“super(形参列表)”,的方式调用父类指定的构造方法。
用法:
1. 规定super(形参列表),必须声明在构造器的首行。
2 . 如果在子类构造器的首行没有显示调用super(形参列表),则子类此构造器默认调用super(),即 调用父类中空参的构造器。
(这么做是为了保证先对父类成员进行初始化)
抽象类
抽象方法
概念:是一种特殊的方法,只有声明,没有具体的实现,必须用abstract关键字修饰,没有方法体.
为什么要有抽象的方法:在一些体系结构的顶端,只需要某些定义功能而没有必要实现,因为不同子类中的实现都不同,这个时候就可以将这个方法声明为抽象方法。
例如定义一个eat的抽象方法:
//抽象类也需要用abstract来修饰 public abstract class Animal { //抽象方法,没有方法体 public abstract void eat(); }
注意:一个类如果包含抽象方法,这个类为抽象类;一个类为抽象类,不一定有抽象方法。
抽象类也需要用abstract关键字修饰。
抽象类的特点:
1. 抽象类不能用来创建对象,其他功能与正常类相同,可以有成员变量,成员方法,构造方法
2. 主要在上层定义功能,让子类继承实现