面向对象编程

面向对象编程

1.初识面向对象

  • 面向过程思想:是一种线性思维,步骤清晰简单,第一步->第二步->第三步…

    面向对象思想:是一种分类的思维模式,将要解决的问题分类,再对这些类单独思考。

  • 面向对象编程(OOP)的本质:以类的方式组织代码,以对象的组织(封装)数据。

  • 类是一组相关属性和行为的集合,可以看成一类事务的模板,使用事物的属性特征和行为特征描述该类事物。(在Java中简单点说就是:类=属性+方法)

    对象是一类事物的具体体现。对象是类的一个实例,必然具备事物的属性和行为。

  • 类与对象的关系:类是一类事物的描述,是抽象的;对象是一类事物的实例,是具体的;类是对象的模板,对象是类的实体。

类与对象的创建:
public class Demo01 {
    public static void main(String[] args) {
        //类实例化会返回自己的对象,student对象就是Student类的实例
        Student student=new Student();
        //给对象name属性赋值
        student1.name="桥本环奈";   
        System.out.println(student.name);
    }
}
//学生类
class Student{
    String name;
    public void study(){
        System.out.println(this.name+"在学习");
    }
}
  • 使用new关键字创建对象的时候,除了分配内存空间,还会给创建好的对象进行默认的初始化以及对类中构造器(也叫构造方法)的调用。

    public class Demo01 {
        public static void main(String[] args) {
            //类实例化会返回自己的对象,student1和student2对象就是Student类的实例
            Student student1=new Student();
            Student student2=new Student();
            //给对象name属性赋值
            System.out.println(student1.name);   //输出为初始化null
            System.out.println(student2.name);   //输出为初始化null
            student1.name="桥本环奈";
            student2.name="大姐大";
            System.out.println(student1.name);   //输出为桥本环奈
            System.out.println(student2.name);   //输出为大姐大
        }
    }
    //学生类模板
    class Student{
    	//构造器(也叫构造方法):创建对象的时候(即new了一个对象),会自动执行一次构造方法
        //构造器特点:1.必须和类名保持一致。2.必须没有返回类型,也不能写void
        //构造器作用:属性进行初始化赋值;
        public Student(){ //这是一个默认构造方法(无参无返回值),创教对象时即使没写也会执行该默认方法
    
        }
        String name;
        public Student(){ 
    		this.name="哇哈哈";   //初始化赋值
        }
        public void study(){
            System.out.println(this.name+"在学习");
        }
    }
    

2.面向对象三大特性

2.1 封装
  • 面向对象三大特性:封装、继承、多态。

  • 程序设计要求:高内聚,低耦合

    ​ 高内聚,低耦合:高内聚指类的内部数据操作细节自己完成,不允许外部干涉;低耦合指类仅暴露少量的方法给外部使用。

  • 封装:数据的隐藏;通常应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。

    Java封装记住:属性私有,get/set

    public class Demo02 {
        public static void main(String[] args) {
            Student1 student1=new Student1();
            student1.setName("桥本环奈");
            student1.setAge(18);
            System.out.println(student1.getName());
            System.out.println(student1.getAge());
        }
    }
    //Student1类  属性私有(private) 调用属性使用get与set方法
    class Student1{
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    }
    
  • 封装的意义:

    1. 提高程序的安全性,保护数据
    2. 隐藏代码的实现细节
    3. 统一接口(get/set)
    4. 系统的可维护性增加了
2.2 继承
  • 继承是类与类之间的关系,继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用extends表示。

  • extends有扩展的意思。子类是父类的扩展。

  • 所有类,或直接、或间接继承Object类。

  • 私有的(private)的变量和方法无法被继承。

  • 子类构造器中会默认先调用父类构造器。(无参构造调无参构造,有参构造调有参构造)

    //Student is 人(Person) 
    public class Student extends Person{}  //Person为父类,Student为子类
    //Teacher is 人(Person) 
    public class Teacher extends Person{}  //Person为父类,Teacher为子类
    
    子类继承了父类,子类就会拥有父类的全部方法。
    public class Person {
        int money=100;
        public void method(){
            System.out.println("我有"+money+"元");
        }
    }
    public class Teacher extends Person{
        //子类默认继承了父类Person类的money属性和method方法
    }
    
    子类构造器中会默认先调用父类构造器。
    public class Person {
        public Person{
        	 System.out.println("Person");
        }
    }
    public class Teacher extends Person{
        public Teacher{
        	//在Teacher无参构造方法中,会默认使用super调用父类无参构造方法
        	//super();  要在构造方法第一行
        	 System.out.println("Teacher");
        }
    }
    输出结果为:Person
    		  Teacher
    
  • super与this关键字

    super注意点:

    1. super调用父类的构造方法,必须在构造方法的第一个
    2. super 必须只能出现在子类的方法或者构造方法中!
    3. super和 this不能同时调用构造方法!

    this:

    1. 代表的对象不同:

      ​ this:本身调用者这个对象

      ​ super:代表父类对象的应用

    2. 前提
      this:没有继承也可以使用
      super:只能在继承条件才可以使用

    3. 构造方法
      this();本类的构造

      ​ super():父类的构造

    public class Person {
        protected String name="fu";
        public void mm(){
            System.out.println("Person");
        }
    }
    
    public class Teacher extends Person{
        private String name="zi";
        public void mm(){
            System.out.println("Teacher");
        }
        public void method(){
            String name="di";
            System.out.println(name);        //这里的name指方法中局部变量name,输出为di
            System.out.println(this.name);   //这里的this.name指本类中成员变量name,输出为zi
            System.out.println(super.name);  //这里的super.name指本类的父类中存在的同名变量name,输出为fu
        }
      public void method2(){
            mm();           //这里的mm方法指本类中的成员方法mm(),输出为Teacher
            this.mm();      //这里的this.mm方法同样指本类中的成员方法mm(),输出为Teacher
            super.mm();     //这里的super.mm方法指本类的父类中的成员方法mm(),输出为Person
        }
    }
    
  • 方法的重写(重写都是方法的重写,和属性无关)

  • 重写:需要有继承关系,子类重写父类的方法。非静态方法可以重写

    1. 方法名必须相同
    2. 参数列表必须相同
    3. 修饰符:范围i可以扩大但不能缩小 public>protected>default>private
    4. 抛出的异常:可以缩小但不能扩大
    public class Person {
        public void mm(){
            System.out.println("Person");
        }
    }
    public class Teacher extends Person{
        @Override
        public void mm(){  //重写了父类的mm()方法
            System.out.println("Student");
        }
    
2.3 多态
  • 多态是方法的多态,属性没有多态
  • 存在条件:继承关系,方法需要重写,父类引用指向子类对象.(注意static静态方法是属于类的,不能被重写;私有方法也不能重写;final常量不能被重写)
public class Person {
    public void test(){
        System.out.println("fu");
    }
    public void p(){
        System.out.println("Person");
    }
}

public class Student extends Person{
    public void test(){
        System.out.println("zi");
    }
    public void s(){
        System.out.println("Student");
    }
}
public class app {
    public static void main(String[] args) {
        //父类的引用指向子类
        //对象能执行哪些方法,主要看左边中的类型有什么方法
         //Student类调用的方法只能是自己的或者继承父类的方法
        Student student=new Student();  左边是Student可以执行test(),s(),p()方法
        //Person类,父类型:可以指向子类,但不能调用子类独有的方法(子类有父类没有的方法),
        Person person=new Student();  左边是Person可以执行test()和p()方法,但test()被子类重写执行子类方法体

        student.test();  //自己调用自己,执行自己的方法,输出为zi
        person.test();   //父类的引用指向子类,父类子类共有方法test,执行子类重写的方法,输出为zi
        student.s();     //这是子类独有的方法s(),父类没有,父类不能执行此方法,只有子类自己调用,输出为Student
        student.p();     //子类继承自父类的方法p(),输出为Person
        person.p();      //父类独有方法可以被子类继承,输出为Person
    }
}
  • instanceof关键字(判断类是否有父子)

    public class Person {
        public void run(){
            System.out.println("run");
        }
    }
    public class Student extends Person{
        public void go(){
            System.out.println("go");
        }
    }
    public class Teacher {
    }
    public class app {
        public static void main(String[] args) {
            //Object -> Person ->Student
            Object object=new Student();  //祖父引用指向子类对象,一条关系链Object指向Person指向Student
            //instanceof关键字,X instanceof Y; X是否与Y存在父子关系
            System.out.println(object instanceof Student);  //在上面关系链当中,object与Student存在父子关系,输出为true
            System.out.println(object instanceof Person);   //在上面关系链当中,object与Person存在父子关系,输出为true
            System.out.println(object instanceof Object);   //在上面关系链当中,object与Object存在父子关系,输出为true
            System.out.println(object instanceof Teacher);  //不在上面关系链当中,object与Teacher不存在父子关系,输出为false
            System.out.println(object instanceof String);   //不在上面关系链当中,object与String不存在父子关系,输出为false
    
            //类型之间的转换:父  子
            //父类转换为子类,向下转型需要强制转换
            Person person=new Student();
            ((Student)person).go();   //person是Person类型不可以执行go()方法,将person类型转换为Student类型就可以执行go()方法。
            //子类转换为父类,向上转型不需要强制转换,但可能会丢失一些子类本来的方法,如下面的转换丢失了go()方法
            Student student=new Student();
            Person p=student;
        }
    }
    
  • static关键字详解

    public class Student {
        private static int age;   //静态变量
        private double score;     //非静态变量
    
        public static void run(){  //静态方法
            System.out.println("run");
        }
        public void go(){    //非静态方法
            System.out.println("go");
        }
    
        static { //静态代码块,类加载时执行一次,并且仅执行一次;记住静态代码块比匿名代码块先执行,匿名代码块又比构造方法先执行
            System.out.println("这是静态代码块,永久且仅执行一次");
        }
        {  //匿名代码块,类加载时执行,可以执行多次
            System.out.println("这是一个匿名代码块");
        }
        
        public static void main(String[] args) {
            Student student=new Student();
            //静态变量与非静态变量
            //静态变量可以通过 类名.变量名 直接调用,也可以通过实例化对象来调用
            System.out.println(Student.age);
            System.out.println(student.age);
            //非静态变量需要通过实例化对象才可以调用,不可以通过 类名.方法名 来调用
            System.out.println(student.score);
    
            //静态方法与非静态方法
            //静态方法可以通过 类名.方法名 直接调用,也可以通过实例化对象来调用
            Student.run();
            student.run();
            //非静态方法可以通过实例化对象来调用,不可以通过 类名.方法名 来调用
            student.go();
        }
    }
    

3.抽象类和接口

3.1 抽象类
  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法那么该方法就是抽象方法,如果修饰类那么该类就是修饰类。

  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定是抽象类。

  • 抽象类中既可以有抽象方法,也可以有普通方法。

  • 不能new抽象类(即不能实例化),只能靠子类去实现抽象类。

  • 抽象类只能单继承(A extends B),不能多继承。

    //abstract 抽象类
    public abstract class A {
        //abstract,抽象方法:只有方法的名字,没有方法的实现
        public abstract void doSome();
    }
    //抽象类的子类(称为实现类)需要实现抽象类的所有抽象方法,除非子类还是抽象类。
    public class B extends A{
        @Override
        public void doSome() {
            System.out.println("DoSome");
        }
    }
    
3.2 接口
  • interface定义接口,接口都要有实现类

  • 接口可以多继承(A implements B,C)

  • 接口不能被实例化,接口中没有构造方法

  • 接口中的方法都是抽象方法

    //interface定义接口,接口都要有实现类
    public interface A {
        //接口中的所有定义的方法其实都是抽象的, public abstract
        //public abstract void run(); 其中public abstract可以省略,因为都是抽象的
        void run();
        void go();
    }
    //类可以实现接口,implements 接口
    //实现接口的类需要重写接口中的方法
    public class AImpl implements A{
        @Override
        public void run() {
            System.out.println("run");
        }
        @Override
        public void go() {
            System.out.println("go");
        }
    }
    

4.内部类

  • 内部类就是在一个类的内部再定义一个类。

  • 包括:

    1. 成员内部类
    2. 静态内部类
    3. 局部内部类
    4. 匿名内部类
    展示成员内部类和静态内部类:
    public class Outer {
         private int id=10;
         public void out(){
             System.out.println("这是外部类的方法");
         }
         public class Inner{   //成员内部类,在类中在方法外
         //public static class Inne{} 静态内部类,比变量方法先执行,所以不用于获取外部类私有属性
             public void in(){
                 System.out.println("这是一个成员内部类的方法");
             }
             //内部类可以获得外部类的私有属性和私有方法
             public void getId(){
                 System.out.println(id);
             }
         }
    }
    public class app {
        public static void main(String[] args) {
            //实例化外部类
            Outer outer=new Outer();
            //通过外部类实例化内部类
            Outer.Inner inner=outer.new Inner();
            inner.getId(); //通过内部类调用外部类私有属性
        }
    }
    
    展示局部内部类:
    public class Outer {
        public void method(){
              class Inner{  //局部内部类,在方法中的类
                public void in(){
                    System.out.println("这是一个局部内部类");
                }
              }
        }
    }
    
    
    展示匿名内部类:
    public class Test {
        public static void main(String[] args) {
            //没有名字初始化类,不用将实例保存到变量中
            new A().method();
        }
    }
    class A{
        public void method(){
            System.out.println("匿名内部类");
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值