面向对象oop

面向对象(oop)

1.初识面向对象

面向过程思想

具体的 步骤清晰,第一步做什么,第二步做什么

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

从认识角度考虑是先有对象后有类,是具体的事物。类,是抽象的,是对对象的抽象。

从代码的角度看考虑是先有类后有对象。

 

2.方法的回顾和加深

    public static void main(String[] args) {

      // 实例化 这个类new
      //非静态方法 ↓ 1.
      Student student = new Student();
      student.say();
      // 2. ↓
      new Student().say();
      //静态方法直接调用 ↓ static
      //Student.say();
  }
    public void say(){
      // say方法
    }

}

 

3.对象的创建分析

类是一种抽象的数据类型,它是对某一种事物整体描述/定义,但是并不能代表某一个具体的事务

例如抽象的概念:动物,植物等

对象是抽象概念的具体实例

创建于初始化对象

使用new关键字创建对象

一个项目应该只存在一个main方法

一个类里面 只有属性和方法

构造器

package com.oop.Demo2;

public class Person {
   public String name;
   public int age;
   //构造器 Alt+(fn)insert
   public Person() {
  }
   //有参构造: 一旦有参构造 想用new对象的话 必须显式定义出来无参构造
   public Person(String name) {
       this.name = name;
  }
   //实例化初始值
   //1.使用new关键字,本质是在调用构造器
   //2.用来初始化值
   public Person(String name, int age) {
       this.name = name;
       this.age = age;
  }
}
   //测试类
/** public class Application {
   public static void main(String[] args) {
       //实例化了一个对象
       Person person = new Person("awdaw",13);
       System.out.println(person.name);
       System.out.println(person.age);
       }
   }
* 构造器:
*     1.必须和类名相同
*     2.没有返回值
* 作用:
*     1. new 本质在调用构造方法
*     2. 初始化对象的值
* 注意点:
*     1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
*     this.XXX 代表这个类的
*/

 定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造

创建对象与内存分析

 

小结类与对象

1.类与方法

类是一个模板 抽象的,对象是一个具体的实例

2.方法

定义,调用

3.对象的引用

引用类型:基本类型(8种)

对象是通过引用来操作的,从 栈 → 堆

4.属性:字段Field 成员变量

默认初始化:

数:0 0.0

char: u0000

boolean: false

其他引用: 都为null

修饰符 属性类型 属性名 = 属性值

5.对象的创建与使用

必须使用new关键字创造对象,构造器 Person names = new Person( );

对象的属性 names . name

对象的方法 names . say( )

6.类 ( 一个类中 只有属性和方法)

静态的属性 就是属性

动态的方法 方法

4.重点:面向对象的三大特性(封装,继承,多态)

封装(属性私有 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 name;

  }
   //set 给这个数据设置值
   public void setName(String name){

       this.name = name;
  }

   public int getAge() {

       return age;
  }
   // set内可以判断安全性
   public void setAge(int age) {
       if (age > 120 || age < 0) {
               this.age = 3;
      } else {
               this.age = age;
      }
  }

   public char getSex() {
           return sex;
  }

   public void setSex(char sex) {
           
       this.sex = sex;
  }

}

测试类

package com.oop;

import com.oop.Demo03.Student;

public class Application {
   public static void main(String[] args) {
       Student s1 = new Student();
       s1.setName("wawa");
       System.out.println(s1.getName());
       s1.setAge(666);//不合法
       System.out.println(s1.getAge());
  }
/**封装的意义
* 1.提高程序的安全,保护数据
* 2.隐藏代码的实现细节
* 3.统一接口 get set
* 4.提高了系统的可维护性
*/

}

 

 

继承

继承的本质是对某一批类的抽象

extends 的意思是“扩展”,子类是父类的扩展。

子类继承了父类,就会拥有父类的全部方法。

//Student子类 继承 Person父类 
public class Student extends Person{
}

四个优先级

//public

//protected(受保护的)

//default(默认的)

//private(私有) 用get /set方法操作

继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖,组合,聚合。

继承关系的链各类,一个为子类(派生类),一个为父类(基类),子类继承父类,使用关键子extends来表示

子类和父类之间具有“is ”的关系。

java中类只有单继承,没有多继承

object类

java中所有的类 都默认直接或间接继承object ctrl+h可以查看继承关系

super

 

 

方法也是和属性一样的调用

但是权限私有的 private 父类的方法 子类通过super不能调用

 

super 注意点:

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

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

3.super和this不能同时出现调用构造方法。同时则报错

4.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造

对比 this

代表的对象不同

this:本省调用者这个对象

super:代表父类对象的应用

前提

this:没有继承也可以使用

super:只能在继承条件才能使用

构造方法

this():本类的构造

super():父类的构造!

 

方法重写 Override

重写 只和非静态方法有关

测试类

public class Application {
   public static void main(String[] args) {
   //静态方法和非静态方法区别很大!!
   // 静态方法 加了static 方法的调用只和左边定义的数据类型有关
       // 重写 只和非静态方法有关
   A a = new A();
   a.text();
   //父类的B引用指向了子类A
   B b = new A(); //子类重写了父类
   b.text();


  }

}

子类A

public class A extends B{

   @Override// 注解 有功能的注释
   public void text() {
       System.out.println("A");
  }
}

父类B

//重写 只有方法
public class B {

   public  void text(){
       System.out.println("B输出");
  }

}

非静态才能重写:需要有继承关系,子类重写父类的方法!

1.方法名必须相同

2.参数列表必须相同,否则就变成方法重载了

3.修饰符: 范围可以扩大 public 》 protected》Default》private

4.抛出异常: 范围可以被缩小 但不能扩大ClassnotFoundException <--Exception(大)

重写:子类方法必须和父类必须一致, 方法体不同

为什么需要重写???

  1. 父类的功能,子类不一定需要,或者不一定满足!

  2. Alt +Insert override

多态

package com.oop.Demo06;

public class Person {
   public void run(){
       System.out.println("DD666");
  }

}
/*
多态注意
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系 类型转换异常! ClassCastException
3.存在条件: 继承关系,方法需要重写,
 两个类都有,父类引用指向子类对象!执行子类

个别方法不能被重写
   1. static 方法,属于类,不属于实例
   2. final 常量 定值
   3. private方法: 私有
*/

子类

public class Student extends Person{
   @Override
   public void run() {
       System.out.println("DD打我");
  }
   public void eat(){
       System.out.println("coco");

  }
}

测试类

package com.oop;

import com.oop.Demo06.Person;
import com.oop.Demo06.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();


       //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
      ((Student)s2).eat();
       s1.run();
       s2.run();//子类重写了父类的方法,由此执行子类

  }

}

 

多态注意
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系 类型转换异常! ClassCastException
3.存在条件: 继承关系,方法需要重写,
两个类都有,父类引用指向子类对象!执行子类

个别方法不能被重写
1. static 方法,属于类,不属于实例
2. final 常量 定值
3. private方法: 私有

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

一个对象类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)

多态存在的条件

有继承关系

子类重写父类方法

父类引用指向子类对象

注意 多态是方法的多态,属性名没有多态性

instanceof 判断一个对象是什么类型

System.out.println(X instanceof Y);//判断能不能编译

X与Y存在有关系就可以

public class Application {
   public static void main(String[] args) {
       //类型转换之间 父   子
       Student student = new Student();
       // 高 转 低 可以任意转换无影响 ↓
       Person student1 = new Student();
       //想让student1这个对象person类 执行 Student类的方法以及独有的run方法
       //低转高 就要强制转换
       Student student11 = (Student) student1;
       //强制转换利用student11对象就可以使用Student
       student11.run();
  }
}

student对象类 想使用Student类的方法 ((Student)student) . run()

/*

1.父类的引用指向子类的对象

2.把子类转为父类,向上转型,反之父类转子类向下转型:需要强制转换可能会丢失些方法

3.方便方法调用,减少重复的代码

static关键字详解

static静态方法 可以在类中任意调用也可被非静态方法调用

public class Student {
   private static int age;//静态的变量      
   private double score;  //非静态的变量

   public void run(){

  }
   public static void go(){

  }
   public static void main(String[] args) {
       run();//直接调不行,
       //必须 new 对象调用
       new Student().run();

 

static 多线程会用到

public class Person {

  {
       //代码块(匿名代码快) 2.匿名代码块 可以用来赋一些初始值
  }
   static{
       //静态代码块 且执行一次   1.最先执行 跟类一起加载
  }

   public Person() {
       //构造方法 3.最后执行构造
  }
}

 

package com.oop.Demo08;
//静态导入包
import static java.lang.Math.PI;
import static java.lang.Math.*;
public class Text {
   public static void main(String[] args) {
       System.out.println(random());
  }
//通过final定义的类不能继承了,
}

通过 final 定义的类不能继承了,

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/li369/p/14071425.html