Java学习之面向对象的三大特性

面向对象编程-2

面向对象三大特性

封装

  1. 封装的含义:数据的隐藏。指禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问。

  • 利用private修饰符使得属性(如name id gender age等)私有化

  • 利用get、set的方法获取private的数据

  • 并可以在set方法中设置数据的合法性

package com.oop.demo03;

public class Student {
   //private:私有 与public不同
   private String name;
   private int id;
   private String gender;
   private int age;
   //get set 作为可以操作private类型属性的方法
   //获得这个数据
   public void setName(String name){
       this.name=name;
  }
   //给这个数据设置值
   public String getName(){
      return this.name;
  }
   public void setAge(int age){
       if (age>=0 && age<=120){
           this.age=age;
      }else {
           this.age=3;
      }
  }
   public int getAge(){
       return this.age;
  }
}
package com.oop.demo03;
public class Application {
public static void main(String[] args) {
   Student s1 = new Student();
   s1.setName("小红象");
   System.out.println(s1.getName());
   s1.setAge(7);
   System.out.println(s1.getAge());
}
}
  1. 封装的意义

01.提高程序的安全性,保护数据

02.隐藏代码的实现细节

03.统一接口,都是用get、set

04.系统可维护性增加

继承

  1. 继承的含义:是类和类之间的关系。子类(派生类) extends 父类(基类)

父类 Person

package com.oop.demo04;
public class Person {
   
   public void say(){
       System.out.println("say something");
  }
   public int money=10_0000_0000;
}

子类Students

package com.oop.demo04;
//extends继承Person类
public class Students extends Person {
}

运行程序

package com.oop;
import com.oop.demo04.Students;

public class Application {
public static void main(String[] args) {
   Students students = new Students();
   students.say();
   System.out.println(students.money);
}
}
  1. 修饰符

  • public:无限制

  • protected

  • default:默认

  • private:限制范围最大

  1. 在Java中,所有的类默认继承Object,Java类中只有单继承没有多继承

  1. super

  • 子类调用父类的属性、方法

package com.oop.demo05super;
public class Person {
   protected String name="Xiuga";
   public void print(){
       System.out.println("Person");
  }
}
package com.oop.demo05super;
public class Student extends Person {//继承了Person类
   private String name="gaga";
   public void test(String name){
       System.out.println(name);//Sugar
       System.out.println(this.name);//本类的name gaga
       System.out.println(super.name);//子类调用父类的属性(name) Xiuga
  }
   public void test2(){
       super.print();////子类调用父类的方法(print) Person
  }
}
package com.oop;

import com.oop.demo05super.Student;

public class Application {
public static void main(String[] args) {
   Student student = new Student();
   student.test("Sugar");
   student.test2();
}
}
  • 子类调用父类的无参构造

package com.oop.demo05super;

public class Person {

   public Person(){
       System.out.println("Person类无参构造执行");
  }
}
package com.oop.demo05super;

public class Student extends Person {
   public Student(){
       //隐藏代码 super();调用了父类的无参构造
       System.out.println("Student类无参构造执行");
  }

}
package com.oop;
import com.oop.demo05super.Student;

public class Application {
public static void main(String[] args) {
   Student student = new Student();
}
}

注意:

01.super调用父类的构造方法,必须在构造方法的第一个

02.super必须只能出现在子类的方法或构造方法中

03.super和this不能同时调用构造方法

04.当父类出现有参构造方法,子类想调用父类的无参构造方法时,父类必须写出无参构造方法

05.super()指调用父类构造方法 this()指调用本类构造方法

  1. 方法的重写@Override

  • 重写:子类的方法和父类一致,方法体不同

  • 重写的条件

01.需要有继承关系,子类重写父类的方法

02.方法名必须相同

03.参数列表必须相同(和方法的重载Overload的区别)

04.父类到子类重写方法的修饰符:范围可以扩大但不能缩小

05.抛出的异常:范围可以缩小但不能扩大

  • 为什么要重写?

父类的功能,子类不一定需要或不一定满足

  • 代码参考

package com.oop.demo05super;

public class Person {
   public /*static*/ void t(){
       System.out.println("Person--t");
  }
}
package com.oop.demo05super;

public class Student extends Person {
   public /*static*/ void t(){
       System.out.println("Student--t");
  }
}
package com.oop;

import com.oop.demo05super.Person;
import com.oop.demo05super.Student;

public class Application {
public static void main(String[] args) {
   Student student = new Student();
   student.t();//Student--t
   Person person=new Student();
   person.t();//Student--t
}
}

t()前没有static时,上述代码为方法的重写,且IDEA中重写的方法旁有图标提示

t()前加上static时

public static void main(String[] args) {
   Student student = new Student();
   student.t();//Student--t
   //方法的调用只和“=”左边即定义的数据类型有关
   Person person=new Student();
   person.t();//Person--t
}

多态

  1. 多态:同一方法可以根据发送对象的不同而采用多种不同的行为方法

//一个对象的实际类型是确定的 
new Student();
new Person();
//可以指向的引用类型就不确定了,这就是多态
Student s1 = new Student();
//父类的引用指向子类
Person s2=new Student();
Object s3=new Student();

package com.oop.demo06;

public class Person {
   public void test(){
       System.out.println("Person");
  }
}
package com.oop.demo06;

public class Student extends Person{
public void test(){//重写的方法
   System.out.println("Student");
}
public void eat(){
   System.out.println("eat");
}
}
package com.oop;

import com.oop.demo06.Person;
import com.oop.demo06.Student;

public class Application {
public static void main(String[] args) {
   //子类(Student)可以调用自己(Student)的和父类(Person)的方法
   Student s1 = new Student();
   s1.test();
   //父类的引用指向子类
   //父类只能调用父类的方法,不能调用子类,若想调用需强制转换
   Person s2=new Student();
   s2.test();
   s1.eat();
   //父类调用子类方法,强制转换
  ((Student)s2).eat();
}
}
  1. 注意

  • 多态是方法的多态,属性没有多态

  • 多态出现在父类子类中,类之间有联系。 否则类型转换异常  ClassCastException

  • 存在条件: 存在继承关系 方法需要重写,重写方法后,执行子类的方法 父类引用指向子类对象 Father f1= new Son();

  • 不能重写的方法:1.含 static 方法 2. 含final的方法 常量 3. 修饰符为private 私有方法

多态的机制

原理也很简单,父类或者接口定义的引用变量可以指向子类或者具体实现类的实例对象,由于程序调用方法是在运行期才动态绑定的,那么引用变量所指向的具体实例对象在运行期才确定。所以这个对象的方法是运行期正在内存运行的这个对象的方法而不是引用变量的类型中定义的方法。

作者:猪_队友 链接:https://www.jianshu.com/p/68ddb5484ca2 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  1. instanceof

instanceof : 用来判断两个类之间是否存在父子关系

x instance of y
//x y 之间有父子关系,则编译通过,不报错;反之,不通过

package com.oop.demo07;

public class Person {
}
package com.oop.demo07;

public class Student extends Person{
}
package com.oop.demo07;

public class Teacher extends Person{
}
package com.oop;
import com.oop.demo07.Person;
import com.oop.demo07.Student;
import com.oop.demo07.Teacher;

public class Application {
public static void main(String[] args) {
   /*
   * Object > Person > Teacher
   * Object > Person > Student
   * Object > String*/
   Object object=new Student();
   System.out.println(object instanceof Object);//true
   System.out.println(object instanceof Person);//true
   System.out.println(object instanceof Student);//true
   System.out.println(object instanceof Teacher);//false Student与Teacher无父子关系,因此为false
   System.out.println(object instanceof String);//false
   Person  person =new Student();
   System.out.println(person instanceof Object);//true
   System.out.println(person instanceof Person);//true
   System.out.println(person instanceof Student);//true
   System.out.println(person instanceof Teacher);//false
   //System.out.println(person instanceof String);//编译报错,因为Person与String没有任何关系
   Student  student =new Student();
   System.out.println(student instanceof Object);//true
   System.out.println(student instanceof Person);//true
   System.out.println(student instanceof Student);//true
   //System.out.println(student instanceof Teacher);//编译报错
   //System.out.println(student instanceof String);//编译报错
}
}
  1. 类型转换

package com.oop;

import com.oop.demo07.Person;
import com.oop.demo07.Student;
import com.oop.demo07.Teacher;

public class Application {
public static void main(String[] args) {
   Person  person =new Person();
   //父类转换为子类--向下转换,方便方法的调用,减少重复代码
   //父类 Person 调用子类 Student 的方法,由高到低,强制转换
  ((Student) person).go();
   //子类转换为父类--向上转换
   //子类 Student 转换为 父类 Person,会丢失自身的方法
   Person person1=new Student();
   //person1.go();
}
}

 

posted @ 2021-02-26 01:26  xiuga  阅读(125)  评论(0)    收藏  举报