1.面向对象基础
通过之前的了解我们知道与C语言这种面向过程语言不同,Java是一门面向对象语言,其操作都是基于类和对象进行的.
1.1面向对象语言的优点
面向对象是一种常见的思想,符合人类的思考习惯
面向对象可以增强代码的复用性,降低程序的耦合度,将复杂的业务逻辑简单化
面向对象具有封装、继承、多态、抽象等特性
1.2类和对象
所谓类,就是对一类事物的归纳,如人类,鸟类
而对象也称实例,是对类中事物特征的具体描述
1.2.1对象的创建
在Java中,万物皆对象。对象的创建通过关键字new
Person cxk = new Person();
可以通过Person cxk
的方式,去创建一个引用,但是并不是一个对象,创建对象引用时,一般希望创建一个新对象与之关联,也就是new Person()
1.3属性和方法
类中一个最基本的要素就是要有属性和方法,对于一个人类来说,属性就是对一个人特征的描述,而方法就是对一个人行为的描述
1.3.1属性
属性也被成为成员变量,可以是基本数据类型,也可以是任意类的对象
//如人的年龄、姓名等
class Person{
int age;
String name;
String sex;
}
1.3.2方法
方法是类的重要组成,表示对某些事情的处理方式
class Person{
int age;
String name = "cxk";
String sex ;
public void rap(){
String name = this.name;
System.out.println(name + "在rap");
}
}
被static修饰的成员变量和方法在类加载时就会被一起加载
1.3.3成员变量及方法的使用
我们在使用成员变量或方法时,一般先new 一个对象,然后使用对象名.成员变量来使用
Person cxk = new Person();
cxk.sex = "女";
cxk.rap();
System.out.println(cxk.sex);
1.4构造方法
构造方法又称构造器和构造函数,与成员方法类似,但是有以下要求
- 方法名与类名相同
- 没有返回值,也不能加void
在创建对象或创建对象时直接对成员变量进行赋值时要使用到构造方法,构造方法分为有参和无参两种
class Person{
int age;
String name = "cxk";
String sex ;
public Person(){
//无参构造,也称空参构造
}
public Person(int age, String name, String sex) {
//全参构造
this.age = age;
this.name = name;
this.sex = sex;
}
public void rap(){
String name = this.name;
System.out.println(name + "在rap");
}
}
如上述代码所示,构造方法的参数个数可以有0~多个,如果类中没有定义构造方法,JVM 会为我们自动生成一个空参构造
public class Chicken {
double money;
String color;
String name;
}
public class Test {
public static void main(String[] args) {
Chicken cxk = new Chicken();
}
}
上述代码能够编译通过就是因为调用了自动生成的空参构造
public class Chicken {
double money;
String color;
String name;
public Chicken(double money, String color, String name) {
this.money = money;
this.color = color;
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
//Chicken cxk = new Chicken();//编译不通过
Chicken cxk = new Chicken(10,,"黑","鸡哥");//编译通过
}
}
如果当我们为类Chicken指定了一个有参构造后,编译还能否通过?
答案是不能,当我们指定了一个有参构造后,会覆盖掉默认的空参构造,如果还想使用空参构造,我们必须显式的写出
public class Chicken {
double money;
String color;
String name;
public Chicken(double money, String color, String name) {
this.money = money;
this.color = color;
this.name = name;
}
public Chicken() {
}
}
public class Test {
public static void main(String[] args) {
Chicken cxk = new Chicken();
}
}
2.面向对象三大特征 - 封装
面向对象语言具有三大特征,即封装、继承和多态
封装是面向对象的一个重要思想,即希望隐藏类的内部细节,只提供一些方法来使外界进行访问
2.1访问权限控制
我们在之前的学习中,常常见到public等修饰符,在Java中,成员变量的访问权限也通过访问修饰符指定,成员变量的访问权限有四种,即
public
:公开的,能在任何位置被访问
protected
:受保护的,只能在同一类中或同一包中或其子类访问
default
(不写):默认的,只能在同一类中或同一包中进行访问
private
:私有的,只能在同一类中进行访问
访问范围\修饰符 | private | 不写 | protected | public |
---|---|---|---|---|
同一类 | ||||
同一包中的类 | ||||
子类 | ||||
其他包中的类 |
2.2封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。–]
- 隐藏信息,实现细节。
2.3 实现封装的步骤
将成员变量设置为private ,
对外提供get、set方法来实现对成员变量的访问
public class Person {
private int age;
private String name;
private String sex;
public Person(int age, String name, String sex) {
this.age = age;
this.name = name;
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
此时访问成员变量,修改成员变量就需要用到get、set
public class Test {
public static void main(String[] args) {
Person cxk = new Person();
cxk.setName("鸡哥");
System.out.println(cxk.getName());
}
}
3.继承
老话说,龙生龙,凤生凤,老鼠的儿子会打洞,
继承就是子类可以继承父类的特征和行为。
卢姥爷和老八都属于男人,而坤坤和乔碧萝都属于女人,男人和女人又都属于人类
虽然男人和女人都具有人类的共同特征,但是二者的属性和行为上又有些许不同
3.1继承的语法格式
class 父类{
}
class 子类 extends 父类{
}
class Animal{
}
class Chicken extends Animal{
}
在Java中,只允许单继承,即每个类只能有一个直接父类,但可以多层继承
在继承时,子类只能继承父类中非private的成员变量和方法
Object 是所有类的父类,也称超类
3.2 final
当一个类被关键字final修饰时,表示该类不可被继承
当一个变量被关键字final修饰时,表示该变量的值不可被修改,即是一个常量
public final class String{}//Java中的String类
public static final int MAX_VALUE = 0x7fffffff;
final用于访问修饰符之后
3.3 this super
this 指向自己的引用
super 可以用来指向父类的变量和方法,实现对父类成员的访问
使用:
//访问成员变量
this.成员变量名 //指向本类的成员变量
super.成员变量名 //指向父类的成员变量
//访问成员方法
this.成员方法名(参数) //调用本类的成员方法
super.成员方法名(参数) //调用父类的成员方法
//调用构造方法
this(参数) //调用本类的构造方法
super(参数) //调用父类的构造方法
public class Animal {
public String name = "菜徐琨";
public String color = "黑色";
int age = 18;
public Animal(String name, String color, int age) {
this.name = name;
this.color = color;
this.age = age;
}
public Animal(String color, int age) {
this.color = color;
this.age = age;
}
public Animal() {
}
void rap() {
System.out.println(this.name + "在rap");
}
}
public class Chicken extends Animal {
public String name = "鸡哥";
public Chicken() {//默认调用父类的无参构造,super()
}
public Chicken( String color, int age) {
super(color, age);//调用父类的两个参数构造方法
}
public void test() {
System.out.println(super.name);
System.out.println(this.name);
super.rap();
this.rap();
}
@Override
void rap() {
System.out.println(this.name + "在rap");
}
}
public class Test {
public static void main(String[] args) {
Chicken chicken = new Chicken("白", 14);
chicken.test();
}
}
3.4方法的重写和重载
当我们继承了父类的某个方法,但是方法体中的代码和父类不同,即方法的具体实现不同于父类,但是和父类具有相同的方法名,形参列表和返回值,这就叫做方法重写.
class Animal {
public void sing(){
System.out.println("菜徐琨在唱");
}
}
class Chicken extends Animal{
@Override//此注解标明方法被重写
public void sing() {
System.out.println("鸡哥在唱");
}
}
方法重载在之前已经介绍过,就不再赘述
注意:
重写方法时子类方法可以和父类方法的权限修饰符不同,但不能低于父类的访问权限,
在重写方法时子类方法可以和父类方法的返回值不同,但其返回值必须是父类方法返回值的子类
class Animal {
public Animal sing(){
return new Animal();
}
}
class Chicken extends Animal{
@Override
public Chicken sing() {
return new Chicken();
}
4.多态
同种数据类型的不同对象对同一方法会有不同的表现形式,这被称为多态
多态可分为编译时多态和运行时多态
4.1多态的条件
多态是建立在继承的基础上的,多态要满足以下条件
- 子类重写了父类的方法
- 父类引用指向子类对象
Animal chicken = new Chicken();
4.2多态的使用
class Animal {
public void sing(){
System.out.println("动物在唱歌");
}
}
class Chicken extends Animal {
@Override
public void sing() {
System.out.println("鸡在唱歌");
}
}
class Dog extends Animal{
@Override
public void sing() {
System.out.println("狗在唱歌");
}
}
public class Test {
public static void main(String[] args) {
Animal chicken = new Chicken();
Animal dog = new Dog();
chicken.sing();//鸡在唱歌
dog.sing();//狗在唱歌
}
}
对于上述代码,虽然chicken和dog的编译类型 都是Animal类型的,但在调用sing()方法时,却有着不同的表现.这是因为对于成员方法来说,编译看左边,运行看右边.
4.3 向上转型与向下转型
在之前基本数据类型我们就了解过,数据类型都是会从小类型转大类型,从大类型转小类型需要强转转换
向上转型向下转型与之类似
4.3.1 向上转型
向上转型就是子类向父类转型.向上转型会自动转换,因为是绝对安全的
Animal chicken = new Chicken();
4.3.2 向下转型
向下转型就是父类向子类转型.向下转型需要进行强制转换,因为不是绝对安全的
Animal chicken = new Chicken();
Chicken cxk = (Chicken)chicken;
4.4 instanceof
instanceof
用来判断一个对象是否是某个类的对象,
如果是某个类的对象的话,可以进行向下转型,这样做比较安全
使用格式:
对象名 instanceof 类名/接口
例:
Animal chicken = new Chicken();
if(chicken instanceof Chicken){
Chicken cxk = (Chicken)chicken;
}