Java基础之面向对象编程(OOP)
初步认识面向对象
-
面向对象思想:
- 物以类聚,分类的思想模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后才对某个分类下的细节进行面向过程的思考。
- 面向对象适合处理复杂的问题,适合处理多人协作的问题。
-
对于描述复杂的事务,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
什么是面向对象:
- 面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据。
- 特性:封装、继承、多态
- 从认识论角度考虑是先有对象后有类。对象,是具体的事务。类,是抽象的、是对对象的抽象。
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
对象的创建分析
类与对象的关系:
- 类似一种抽象的数据类型,它是对某一类事务整体描述/定义,但是并不能代表某一个具体的事务。
- 对象是抽象概念的具体实例。
创建与初始化对象:
- 使用new关键字创建对象。
- 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的。并且构造器有以下两个特点:必须和类的名字相同;必须没有返回类型,也不能写void。
- 构造器必须要掌握。
面向对象的三大特性
- 封装:
封装(数据的隐藏),通常,应禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问,这就是信息隐藏。属性私有,get/set
重点:“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合就是仅暴露少量的方法给外部使用。
//封装 alt+insert 快捷键自动生成get/set方法
public class Student {
private String name;//姓名
private Integer id;//学号
private char sex;//性别
private Integer age;//年龄
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
if (age>140||age<0) {//不合法
// System.out.println("年龄输入不合法!");
this.age=0;
}else {
this.age = age;
}
}
}
++++++++++++++++++++++++++++++++++++++++++++++
实现代码:
//封装
public class Application {
/*
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护性增加了
*/
public static void main(String[] args) {
Student student = new Student();
student.setName("郭牛逼");
System.out.println(student.getName());
student.setAge(9);
System.out.println(student.getAge());
}
}
-
继承:
- 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
- extends的意思是“扩展”。子类是父类的扩展。
- Java中类只有单继承,没有多继承。
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
有关super讲解:
Person类 父类
public class Person {
protected String name="郭鬼";
}
Student类 子类
public class Student extends Person {
private String name="郭萨比";
public void test(String name){
System.out.println("========");
System.out.println(name);//郭皮子坟
System.out.println("========");
System.out.println(this.name);//郭萨比
System.out.println("=========");
System.out.println(super.name);//郭鬼
}
}
测试类
//ctrl+h 快捷键查看继承
//私有的东西不能被继承
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("郭皮子坟");
}
}
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个。
- super必须只能出现在子类的方法或者构造方法中。
- super和this不能同时调用构造方法。
与this的比较:
- 代表对象的不同:
this:本身调用这个对象。
super:代表父类对象的应用。 - 前提:
this:没有继承也可以使用。
super:只能在继承条件下使用。 - 构造方法:
this:调用本类的构造。
super:调用父类的构造。
- 多态
- 多态就是同一种方法可以根据发送对象的不同而采取多种不同的行为方式。一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
- 多态存在的条件:有继承关系;子类重写父类方法;父类引用指向子类对象。
- 多态是方法的多态,属性没有多态性。
- instanceof (类型转换)引用类型转换 判断一个对象的类型
//父类
public class Person {
public void run(){
System.out.println("郭皮子坟");
}
}
================================================
//子类
public class Student extends Person {
@Override
public void run() {
System.out.println("郭鬼");
}
public void eat(){
System.out.println("eat");
}
}
==============================================
//测试类
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//一个对象的引用类型是不确定的
Student student=new Student();//Student 能调用的方法都是自己的或者继承父类的方法
Person person= new Student();//Person 父类型,可以指向子类,但是不能调用子类独有的方法
Object object =new Student();
//对象能执行那些方法,主要看对象左边的类型,和右边的关系大不大
//person.run();//子类重写了父类的方法,执行子类的方法
//student.run();
student.eat();
// ((Student) person).eat();强转调用子类
}
}
抽象类和接口
- 抽象类:
- abstract修饰符可以用来修饰方法也可以用来修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
- 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
- 抽象类不能使用new关键字来创建对象,他是用来让子类继承的。
- 抽象方法只有方法的声明,没有方法的实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
//abstract 抽象类(类~需要继承) 只有单继承 但是(接口可以多继承)
public abstract class Action {
//abstract 用于约束
//abstract 抽象方法 只有方法名,没有方法的实现。
public abstract void run();
}
++++++++++++++++++++++++++++++++++++++++++++
//抽象类的所有方法,继承了它的子类,都必须要实现他的方法 除非子类也是abstract类型的抽象类,那就需要继续继承子子类。
public class A extends Action {
@Override
public void run() {
System.out.println("郭鬼");
}
}
++++++++++++++++++++++++++++++++++++++++++++++++
测试类
public class Application {
public static void main(String[] args) {
// Action action = new A();
// action.run();
A a = new A();
a.run();
}
}
- 接口:
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。
- 接口的本质是契约。就像法律一样,制定好就需要遵循。
- OO的精髓是对对象的抽象,最能体现这一点的就是接口。(声明类的关键字是class 声明接口的关键字是interface)
//接口1
public interface UserService {
//接口都需要实现类
//接口的所有定义都是抽象的 public abstract (默认)
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
//接口2
public interface TimeService {
void timer();
}
//接口1,2的实现类
public class UserServiceImpl implements UserService,TimeService {
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
内部类及OOP实战
-
内部类就是在一个类的内部再定义一个类。比如:A类中定义一个B类,那么B类相对于A类来说就称为内部类,而A类相对于B类就是外部类了。
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
public class Outer {
private int id;
public void out(){
System.out.println("这是外部类的方法!");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法!");
}
//内部类调用外部类的私有属性
public void getId(){
System.out.println(id);
}
}
//局部内部类
// public void method(){
// class Inner{
// public void in(){
// System.out.println("局部内部类");
// }
// }
// }
}
++++++++++++++++++++++++++++++++++++++++++++++++
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getId();
//outer.method();
}
}
继续坚持,努力!!!