09.面对对象编程
面向对象编程
1、初识面向对象(object-oriented programming)
- 面向对象编程(object-oriented programming,OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)代码。
- 面对对象编程的三大特性
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
- 从代码允许角度考虑是现有类后有对象。类是对象的模板。
2、类和对象的关系
- 类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但并不能代表某一个具体的事物。
- 对象是抽象概念的具体实例
3、对象的创建分析
-
使用new关键字创建对象
classType objectName = new classType(); -
使用new关键字创建的时候,除了分配内存空间外,还会调用构造器对对象的属性值进行初始化
-
类的结构器也称为结构方法,是再进行创建对象的时候必须要调用的。
-
构造器
- 一个类有个默认的方法,该方法被称为构造方法,即构造器。
- 特点
- 和类名相同
- 没有返回值
- 作用
- 初始化对象的属性值
- 注意点
- 定义有参构造器之后,要使用无参构造,必须显示的定义一个无参构造。
//构造器定义例子。 public class Person {//类 String name; //无参构造器 public Person(){} //有参构造器 public Person(String name){ this.name = name; } //alt+insert,快捷生成构造器等(idea上可用) }
4、面向对象三大特征
一、封装
1.为什么要封装
我们程序设计要求”高内聚,低耦合“。高内聚即类的内部数据操作细节自己完成,不允许外部干涉;低耦合即仅暴露少量的方法给外部使用。
通常,应禁止直接访问一个对象中的数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
2.如何封装
使用属性私有(private)、方法get、set实现,实例如下
package com.oop.demo04;
public class Student {
//属性私有
private String name ;
private char sex;
//提供一些可以操作这些属性的方法!public 的 get、set方法
//get 获得名字数据
public String getName(){
return name ;
}
//set 设置名字数据
public void setName(String name){
this.name = name;
}
//get 获得性别数据
public char getSex(){
return sex;
}
//set 设置性别数据,并对性别做限制
public void setSex(char sex){
if (sex == '男' || sex == '女')
{
this.sex = sex;
}else {
System.out.println("你是太监吗");
}
}
}
//idea中alt+insort可以快速创建set、get方法。
3.封装的特点:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护性增强
二、继承
1、继承的概念及用法
- 继承的本质是对一批类的抽象,如下图对人这一类抽象出学生类、教师类。
- 继承是类与类的一种关系,其中人称为父类(基类),学生、教师称为子类(派生类)。类与类之间的关系除继承外,还要组合、依赖、聚合等。
-
Java中只有单继承,无多继承。即:一个父类可以有多个子类,而一个子类只能有一个父类
-
java中子类继承父类使用extend关键字,伪代码如下:
public class Person { private int money = 10_0000_0000;//私有属性 public String name; public void say(){ System.out.println("说了一句话"); } public int getMoney(){ return money; } public void setMoney(int money){ this.money = money; } }//父类,人 public class Student extends Person {}//子类,教师 public class Student extends Person {}//子类,学生 //idea中ctrl+H可以看类的上下层关系 -
java中子类拥有父类的所有公有属性和公有方法
-
java中所有的类,都默认直接或者间接基础Object类
-
被final修饰的类是不可以被继承的。
2、super、this
- super()调用父类的构造方法,默认存在于子类构造方法的第一个。
- super只能出现在子类的方法中。
- this:表示自身类
- super:表示父类
3、方法重写
- 需要有继承关系,子类重写父类的方法
- 方法名、参数列表必须相同,且不能是静态方法
- 修饰符的范围可以扩大不能缩小:public > protected > default > private
- 抛出的异常范围可以缩小不能扩大
- 重写是方法重写,属性没有重写
三、多态
1、多态的概念
- 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
- 一个对象的实际类型是确定的,但指向该对象的引用的类型可以有多种(父类、有关系的类)
2、多态的存在条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
3、注意事项
- 多态是指方法的多态,属性没有多态
4、代码实现
//父类:人
public class Person {
public void test(){
System.out.println("person");
}
}
//子类:学生
public class Student extends Person{
public void test() {
System.out.println("student");
}
}
//测试类
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的,指向该对象的引用类型可以是多种的
//同一方法根据发送对象的不同而采用不同的行为方式
Student student1 = new Student();
student1.test();
Person student2 = new Student();
student2.test();
Person student3 = new Person();
student3.test();
}
}
/*
执行结果如下:
student
student
person
*/
5、instanceof、static、类型转化、代码块
-
instanceof:
该运算符前一个操作符是一个引用变量,后一个操作符通常为一个类(可以是接口),用于判断前面得对象是否是后面得类或者其子类,是则返回ture,否则返回false。【注:若前者与后者没有关系编译器报错】
-
static:
被static修饰的属性和方法是和类一起被加载的,再当前类中可以直接被调用,不用new对象。
package com.oop.demo07; public class Person { public static int age; public double money; public static void main(String[] args) { System.out.println(Person.age);//直接调用 Person s1 = new Person(); System.out.println(s1.money);//new对象调用 } } -
代码块、构造方法的执行顺序
静态代码块-->匿名代码块-->构造方法;其中静态代码块只执行一次。
package com.oop.demo07; public class Student { public Student() { System.out.println("构造方法"); } //可以用于赋初始值 { System.out.println("匿名代码块"); } //只执行一次 static { System.out.println("静态代码块"); } public static void main(String[] args) { Student student = new Student(); System.out.println("=============="); Student student1 =new Student(); } } /* 执行结果如下: 静态代码块 匿名代码块 构造方法 ============== 匿名代码块 构造方法 */ -
类型转化:
- 子类转换为父类,向上转型,可能会丢失方法
- 父类转换为子类,向下转型,需要强制转换
6、抽象类和接口
一、抽象类
- 定义抽象类:使用abstract关键字修饰的类,为抽象类。
- 定义抽象方法:使用abstract关键字修饰的方法,为抽象方法。
- 特点
- 不能实例化。
- 抽象类中可以写普通方法,抽象方法只能出现再抽象类中。
- 抽象类的所有抽象方法,其子类都必须通过重写方法实现,除非其子类也是抽象类。
二、接口
- 定义接口:使用intertface关键字修饰,为接口
- 接口的特点:
- 接口中所有定义方法都是抽象的,默认用修饰符“public abstract”修饰的,是可以缺省的。
- 接口中所有定义的属性都是默认用修饰符“public static final”修饰的,是可以缺省的。
- 接口不能被实例化,接口中没有构造函数,想要使用接口,需要用类去实现
- 如何使用接口:
- 通过类使用关键字implement去实现。
- 其实现的类必须重写接口中的所有方法
- 接口的作用:
- 起约束作用,定义一些方法,可以有不同的实现
- 可以起到多继承的效果
7、内部类
一、内部类
-
成员内部类
package com.oop.demo10; //Inner1为成员内部类 //Inner2为内部类 //一个java类中可以定义多个class类,但是只能有一个public class public class Test { public class Inner1{ } } class Inner2{ } -
静态内部类
package com.oop.demo10; //Inner1为静态内部类 //静态内部类不能访问外部类的非静态属性,因为静态内部类和外部类一起被加载,此时的非静态属性还没被定义。 public class Test { public staic class Inner1{ } } -
局部内部类
package com.oop.demo10; //Inner1为局部内部类 //局部内部类存在于方法中,且不能用public static 修饰 public class Test { public void run(){ class Inner1{ } } } -
匿名内部类
package com.oop.demo10; //user、userservice为匿名内部类 //匿名内部类主要用于实现接口和抽象类,由于不能实例化,所有可以采用匿名内部类的方式。 public class Test { public static void main(String[] args) { User user = new User(){ @Override public void name() { System.out.println("name"); } }; Userservice userservice = new Userservice(){ @Override public void hello() { System.out.println("hello"); } }; user.name(); userservice.hello(); } } abstract class User{ public abstract void name(); } interface Userservice{ void hello(); }

浙公网安备 33010602011771号