java面向对象编程

1.初识面向对象

1.java核心就是面向对象编程

    oop----面向对象编程

     oo----面向对象

2.面向过程思想:步骤清晰简单,第一步做什么,第二步做什么…

​                            面向过程适合处理一些较为简单的问题。

   面向对象思想:物以类聚,分类的思维,首先解决问题需要哪些分类,
                            然后对这些分类进行单独思考,
                            最后才对某个分类下的细节 进行面向过程的思索。
​                            面向对象适合处理复杂的问题,适合处理需要多人协作的问题。

3.面向对象与面向过程不可分割

   面向对象-----框架

   面向过程-----具体实施

4.oop的本质就是:以类的方法组织代码,以对象的形式封装数据

5.oop的三大特性:封装,继承(子类,父类),多态

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

   从代码运行角度考虑是先有类后有对象。类是对象的模板。

 
 

2.类和对象的创建

1.定义:

​               是一种抽象的数据类型,它是对某一类事物整体的描述,并不代表某一具体的事物。

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

2.new关键字创建对象

//以后不要在每一个类里都加上main方法了
public class Demo01 {
    //属性:字段
    String name;   //默认值null
    int age;       //默认值0

    //方法
    public void study(){
        System.out.println(this.name+"在学习");
    }
}

/*

//一个项目应该只存在一个main方法,测试类
public class Application {
    public static void main(String[] args) {
        //类的实例化
        //类实例化后会产生一个自己的对象!
        //Demo01类的对象是xiao
        Demo01 xiao = new Demo01();
        xiao.name = "小明";
        xiao.age = 6;
        System.out.println(xiao.name);
        System.out.println(xiao.age);
    }
}

 */

 
 

3.构造器

1.无参构造器

public class Person {
    //一个类即使什么都不写,它也会存在一个方法
    String name;
    //显示构造器,无参构造器
    // 所以说构造器的作用是实例化初始值
    //使用new关键字本质上是在调用构造器
    public Person(){
        this.name = "小明";
    }
}

public class Application {
    public static void main(String[] args) {
      Person person = new Person();
        System.out.println(person.name);      //小明
    }
}

2.有参构造器

public class Person {
    String name;
    public Person(){}   
//有参构造器:一旦定义了有参构造器,还要使用无参构造的话,就要无参构造器必须显式定义,否则无效
    public Person(String name) {
        this.name = name;
    }
    
public class Application {
    public static void main(String[] args) {
      Person person = new Person("xiao");
        System.out.println(person.name);      //xiao
    }
}

另外:快捷键Alt+Insert生成构造器

3.特点

构造器首先方法名和类名相同,其次没有返回值

 
 

4.内存分析

在这里插入图片描述

附代码如下:

public class Pet {
    public String name;
    public int age;
    public void shout() {
        System.out.println("叫了一声");
    }
}

public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name = "汪";
        dog.age = 1;
        dog.shout();
        System.out.println(dog.age);
        System.out.println(dog.name);

        Pet cat = new Pet();
    }
}

  
 

5.封装(get,set)

1.我们程序设计追求**”高内聚,低耦合“**:

                         ​ 高内聚是指类的内部数据操作细节自己完成,不许外部干涉;

​                          低耦合是指仅暴露少量方法给外部使用。
 
对于代码来说:属性私有 get/set

快捷键:Alt+Insert 自动生成get,set

public class Student {
    //属性私有,外部无法调用
    private String name;
    private int id;
    private char sex;
    private int age;
    //提供能够操作这些属性的方法!
    //提供一些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 > 100 || age < 0) {
            this.age = 3;
        }else{
            this.age = age;
        }
    }
}


public class Application {
    public static void main(String[] args) {
      Student s = new Student();
        s.setName("x");
        System.out.println(s.getName());  //x
        s.setAge(999);
        System.out.println(s.getAge());  //3
    }
}

2.封装的好处

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

2.隐藏代码实现细节

3.统一接口:get,set(可进行安全性检测)

4.系统可维护性增加了

 
 

6.继承

1.继承的本质是对某一批类的抽象,继承是类与类之间的一种关系,除此之外,类和类之间还有依赖、组合·、聚合·等。继承关系的两个类,一个为子类(派生类),一个为父类(基类),子类继承父类,使用关键字extends来表示。

2.java中只有单继承,没有多继承(接口可以多继承)。(一个儿子只可以有一个爸爸,一个爸爸可以有多个儿子)

3.在java中所有的类都默认直接或者间接继承object类。(ctrl+h查看继承关系)

在这里插入图片描述

 

//父类People
package oop.Demo02;
public class People {
    public int money = 10_0000_0000;
    public void say(){
            System.out.println("说了一句话");
    }
}
//子类  学生 is 人
package oop.Demo02;
public class Student1 extends People{

}
//测试类
package oop;
import oop.Demo02.Student1;

//一个项目应该只存在一个main方法,测试类
public class Application {
    public static void main(String[] args) {
        Student1 student = new Student1();
        student.say();
        System.out.println(student.money);
    }
}
/*四个优先级
  public
  protected
  default
  private
 */

 
 

7.Super(调用父类)

1.注意点:

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

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

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

2. super VS this:

​           带表对象不同:

​                     this本身调用者这个对象

​                     super代表父类对象的应用

​            前提不一样:

​                     this:没有继承也可以使用

​                     super:只能在继承条件下使用

​             构造方法:

​                      this():本类的构造

​                      super():父类的构造

 

//父类
package oop.Super;
public class Demo03 {
    public Demo03() {
        System.out.println("父类的无参构造执行了");
    }

    //私有的(private)东西无法被继承
    protected String name = "小明";
    public void print(){
        System.out.println("java");
    }
}
//子类
package oop.Super;
public class Demo04 extends Demo03 {
    public Demo04() {
        //隐藏代码调用了父类的无参构造器
        super();//可以不写,调用父类的构造器,必须在子类的第一行
        System.out.println("子类的无参构造执行了");
    }

    private String name = "小红";
    public void print(){
        System.out.println("jav");
    }
    
    public void text1(){
        print();
        this.print();
        super.print();
    }
    public void text(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }
}
//测试类
package oop;
import oop.Super.Demo04;

//一个项目应该只存在一个main方法,测试类
public class Application {
    public static void main(String[] args) {
      Demo04 s = new Demo04();
      s.text("xiao");
      s.text1();
    }
}

运行结果:

在这里插入图片描述

  
 

8.方法重写(Override)

1.注意点:

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

  2.重写都是方法的重写,和属性无关

  3.方法名必须相同,参数列表也必须相同,方法体不同

  4.重写只和非静态方法有关

  5.修饰符范围从父类到子类可以扩大,public>protected>default(默认)>private

  6.重写快捷键Alt+Insert 在这里插入图片描述

​             @Override//注解:有功能的注释

  7.重写可能会抛出异常:范围可以被缩小,但不可以扩大(父类欠100,子类欠1000就会抛出异常)。

 

2.重写在有无static的区别

1.静态方法时

//父类
package oop;
public class B {
    public static void test(){
        System.out.println("B-test()");
    }
}


//子类
package oop;
public class A extends B {
    public static void test(){
        System.out.println("A-test()");
    }
}


//测试类
package oop;
//一个项目应该只存在一个main方法,测试类
public class Application {
    public static void main(String[] args) {
       //方法的调用只和左边,即定义的类型有关
       A a = new A();
       a.test();
      
       B b = new A();         //父类的引用指向子类
       b.test();
    }
}

运行结果:

在这里插入图片描述

2.非静态方法时:(重写)

//父类
package oop;
public class B {
    public void test(){
        System.out.println("B-test()");
    }
}


//子类
package oop;
public class A extends B {
    public void test(){
        System.out.println("A-test()");
    }
}


//测试类
package oop;
//一个项目应该只存在一个main方法,测试类
public class Application {
    public static void main(String[] args) {
       
       A a = new A();
       a.test();
      
       B b = new A();         //子类对父类的重写
       b.test();
    }
}

运行结果·:

在这里插入图片描述

3.为什么要重写

因为父类的功能,子类不一定需要,或者不一定满足。

 
 

9.多态

1.定义:

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

2.注意事项:

  1.多态是方法的多态,属性没有多态

  2.存在条件:

​          首先得有继承关系,否则报错ClassCastException

​          其次方法要重写,但是 有些方法不能够被重写:1.static   2.final常量   3.private

​          父类引用指向子类,Father f1 = new Son();

​ 

//父类
package oop;
public class Person1 {
    public void run(){
        System.out.println("run");
    }
}
//子类
package oop;
public class Student2 extends Person1 {
    public void run(){
        System.out.println("ru");
    }
    public void eat(){
        System.out.println("eat");
    }
}
//测试类
package oop;
//一个项目应该只存在一个main方法,测试类
public class Application {
    public static void main(String[] args) {
        // 一个对象的实际类型总是确定的
        // new Student2();
        // new Person1();
        
        //但是指向引用类型就不确定了,父类的引用指向子类
        Student2 s1 = new Student2();
        Person1 s2 = new Student2();
        Object s3 = new Student2();
        
        s2.run();
        //Student2子类型能调用的方法都是自己的,或者从父类那里继承过来的
        s1.run();
        //对象能执行哪个方法,主要看的是左边的类型,和右边关系不大
        //Person1父类型可以指向子类,但是不用调用子类型的方法
        ((Student2) s2).eat();//此处是强制转换为子类,如果直接写s2.eat();这样写会报错,因为父类没有eat()方法
    }
}

输出结果:

在这里插入图片描述

 
 

10.instanceof和类型转换

1.instanceof

定义:判断一个对象是什么类型,是否有继承关系。

//前提如下:
//建立了一个父类person2
//两个子类student3和teacher
public class Application {
    public static void main(String[] args) {
        Object object = new Student3();
        Person2 person = new Student3();
        Student3 student = new Student3();
        System.out.println(object instanceof Student3);//True
        System.out.println(object instanceof Person2);//True
        System.out.println(object instanceof Object);//True
        System.out.println(object instanceof Teacher);//flase
        System.out.println(object instanceof String);//flase
        System.out.println("==============================");
        System.out.println(person instanceof Student3);//True
        System.out.println(person instanceof Person2);//True
        System.out.println(person instanceof Object);//True
        System.out.println(person instanceof Teacher);//flase
        //System.out.println(person instanceof String);//编译失败
        System.out.println("==============================");
        System.out.println(student instanceof Student3);//True
        System.out.println(student instanceof Person2);//True
        System.out.println(student instanceof Object);//True
        //System.out.println(student instanceof Teacher);//编译失败
        //System.out.println(student instanceof String);//编译失败
    }
}

 

2.类型转换

低----->高 自然转换

高----->低 强制转换

//子类
public class Student3 extends Person2 {
    public void go(){
        System.out.println("go");
    }
}

//测试类
public class Application {
    public static void main(String[] args) {
        //高转低
        Person2 s = new Student3();
        Student3 s1 = (Student3)s;   //方法一
        s1.go();
        ((Student3) s).go();        //方法二

        //低转高
        Student3 student = new Student3();
        Person2 person = student;
        //低转高可能会丢失自己本来的一些方法
    }
}

  
 

11.static

1.静态变量

​    静态变量可以用类直接调用

public class Static {
    private static int age;
    private double score;

    public static void main(String[] args) {
        Static s = new Static();
        System.out.println(s.score);
        System.out.println(s.age);
        System.out.println(Static.age);         //静态变量可以用类直接调用
        //System.out.println(Static.score);     //非静态变量用类调用会报错
    }
}

2.静态方法

​    静态方法可以直接调用,无需new

public class Static {
    public static void go(){
       run();      //报错,静态方法无法调用非静态方法,因为static方法先加载,此时非static的方法还没有
    }
    public void run(){
        go();
    }
    public static void main(String[] args) {
         go();        
         new Static().run();
    }

3.静态代码块

static{

​        //代码

}

public class Demo05 {
    
    //功能:可以赋初始值
    {
        System.out.println(" 匿名代码块");
    }
    
    //最先执行,而且只执行一次!
    static {
        System.out.println(" 静态代码块");
    }
    
    public Demo05() {
        System.out.println(" 构造方法");
    }


    public static void main(String[] args) {
        Demo05 s = new Demo05();
        System.out.println("======================");
        Demo05 s1 = new Demo05();
    }
}

输出结果:

在这里插入图片描述

4.静态导入包

package oop;
import static java.lang.Math.random;
public class Demo06 {
    public static void main(String[] args) {
        //导入静态导入包后就可以不写System.out.println(Math.random());而写下面这个
        System.out.println(random());
    }
}

 
 

12.抽象类(abstract)

特点:

1.不能new出来,是种约束,只能靠子类去实现

2.抽象类里可以写普通方法,但抽象方法必须写在抽象类里

//abstract抽象类
public abstract class Action {
    //是约束
    //abstract抽象方法,只有方法名字,没有实现!需要别人(子类)帮我们实现
    public abstract void dosomething();
}
//子类
//抽象类的所有方法都需要继承它的子类去实现,除非子类也是抽象类
public class Action1 extends Action {
    @Override
    public void dosomething() {

    }
}

 
 

13.接口(interface代替了class)

特点:

1.接口是专业的约束,接口的本质是锲约,制定好后大家都要遵守,面向接口编程。

2.定义一些方法,让不同人去实现

3.方法public,abstract

4.常量public,static,final

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

6.implements可以实现多个接口、多继承,extends实现单继承

7.必须重写接口中的方法

//接口类
//interface接口关键字,接口都需要有实现类,实现类在接口类名基础上加上Impl
public interface UserService {
    //常量都是public,static,final
    int age = 99;
    //接口中所有定义的方法其实都是public,abstract
    void add();
    void delete();
    void update();
    void query();
}


//接口类
public interface TimeService {
    void time();
}


//实现类
//多继承~利用接口实现多继承implements
public class UserServiceImpl implements UserService,TimeService{
    @Override
    public void add() {

    }

    @Override
    public void delete() {

    }

    @Override
    public void update() {

    }

    @Override
    public void query() {

    }

    @Override
    public void time() {

    }
}

 
 

14.内部类(了解即可)

public class Outer {
    private int Id=10;
    public void out(){
        System.out.println("这是外部类的方法");
    }
    public class Inner{
        public void in(){
            System.out.println("这是内部类的方法");
        }
        //获得外部类的私有属性
        public void getID(){
            System.out.println(Id);
        }
    }
}


//测试类
public class Application {
    public static void main(String[] args) {
         Outer outer = new Outer();
         Outer.Inner inner = outer.new Inner();
          inner.in();          //这是内部类的方法
          inner.getID();       //10
    }
}
//匿名类
public class Application {
    public static void main(String[] args) {
        //没有名字的初始化类,不用将实例化保存到变量中
        new Apple().eat();
    }
}
class Apple{
    public void eat(){
        System.out.println("吃苹果");
    }
}
//局部内部类
public class Outer {
    public void method(){
        class inner{
            public void in(){

            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值