什么是面向对象
- 面向对象编程(oop)的本质就是: 以类的方式组织代码,以对象的形式封装数据
- 从认识论角度考虑是先有对象后有类。对象是具体的事物。类是抽象的,是对对象的抽象。
- 从代码运行角度考虑是先有类后有对象,类是对象的模板
创建与初始化对象
-
使用new关键字创建对象
-
使用new关键字创建时,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
-
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 必须和类名相同
- 必须没有返回类型,也不能写void
package com.oop.Demo01;
public class Person {
//一个类即使什么也不写,他也会存在一个方法
String name;
//构造器:1.和类名相同
// 2.没有返回值
//1.使用new关键字,本质是在调用构造器
//2.用来初始化值
//无参构造
public Person(){
}
//有参构造:一旦定义了有参构造,无参构造必须显示定义
public Person(String name){
this.name=name;
}
}
package com.oop.Demo01;
public class Application {
public static void main(String[] args) {
//new 实例化了一个对象
Person person = new Person("ding");
System.out.println(person.name);
}
}
封装
- 封装(数据的隐藏):通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏(高内聚,低耦合)。
- 记住这句话就够了:属性私有,get/set
get/set作用方法
package com.oop.Demo03;
//类 private:私有
public class Student {
//属性私有
private String name;//名字
private int age;//年龄
private char sex;//性别
//提供一些可以操作这个属性的方法!
//提供一些public的get set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name){
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120||age<0){//不合法年龄
this.age=3;
}
else {
this.age = age;
}
}
}
package com.oop.Demo03;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.setName("九九香");
System.out.println(student.getName());//九九香
student.setAge(200);
System.out.println(student.getAge());//3
}
}
封装的作用
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统的可维护性增加了
继承
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,用关键字:extends表示。
object类
package com.oop.Demo04;
//在Java中所有的类,都默认直接或者间接继承object
//Person 人 父类
public class Person {
private int money=10_0000_0000;
public void say(){
System.out.println("说了一句话!");
}
public int getMoney(){
return this.money;
}
public void setMoney(int money){
this.money=money;
}
}
package com.oop.Demo04;
//Student is 人
public class Student extends Person {
}
package com.oop;
import com.oop.Demo04.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
student.setMoney(10_0000_0000);
System.out.println(student.getMoney());
}
}
Super
注意点:
- super调用父类的构造方法,且必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法!
package com.oop.Demo05;
public class Student extends Person {
public Student() {//无参构造器
//隐藏代码:调用了父类的无参构造
super();//调用父类的构造器,必须要在子类构造器的第一行
System.out.println("Student无参执行了");
}
private String name="Studentname";
public void print(){
System.out.println("Student执行中");
}
public void test1(){
print();
this.print();
super.print();
}
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);//输出父类的name
}
}
package com.oop.Demo05;
public class Person {
public Person() {
System.out.println("Person无参构造执行了");
}
public Person(String name) {
this.name = name;
}
protected String name="Personname";
//私有的东西无法被继承
public void print(){
System.out.println("Person执行中");
}
}
package com.oop;
import com.oop.Demo05.Person;
import com.oop.Demo05.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
//student.test("传入的name");
//student.test1();
}
}
方法重写
需要有继承关系,子类重写父类的方法!子类的方法和父类一致;方法体不同
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小:public > Protected > Default > private
- 抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException--->Exception(大)
为什么要重写?
- 父类的功能,子类不一定满足,或者不一定满足
Alt + Insert: override;
package com.oop.Demo06;
public class A extends B{
@Override //注解:有功能的注释
public void test() {
//super.test();
System.out.println("A=>test()");
}
/*
public void test(){
System.out.println("A=>test");
}*/
}
package com.oop.Demo06;
public class B {
public void test(){
System.out.println("B=>test()");
}
}
package com.oop;
import com.oop.Demo06.A;
import com.oop.Demo06.B;
public class Application {
//静态方法和非静态的方法区别很大
//静态方法://方法的调用只和左边,定义的数据类型有关
//非静态方法:重写
public static void main(String[] args) {
A a = new A();
a.test();//A=>test()
//父类的引用指向了子类
B b = new A();//子类重写了父类的方法
b.test();//A=>test()
}
}
多态
-
即同一方法可以根据发送对象的不同而采用多种不同的行为方式
-
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类,有关系的类)
-
多态存在的条件:
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象
-
注意:多态是方法的多态,属性没有多态性
-
instanceof (类型转换)引用类型
package com.oop.Demo07;
public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.Demo07;
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
package com.oop;
import com.oop.Demo07.Person;
import com.oop.Demo07.Student;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了:父类的引用指向子类
//Student 能调用的方法都是自己的或者继承父类的!
Student s1 = new Student();
//Person 父类型,可以指向子类,但是不能 调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
//可以执行哪些方法,主要看对象左边的类型,和右边关系不大!
s2.run();//子类重写了父类的方法,执行子类的方法
s1.run();
s1.eat();
((Student)s2).eat();
}
}
\