JavaBase 面向对象

Java是一门面向对象的语言

           面向对象分析    OOA

           面向对象设计    OOD

           面向对象编程    OOP

实体:看得见摸得着的物体  对生活中的实体进行分类

       生活中的每一个实体对应着Java中的一个对象

类和对象的关系:

         1.类是对象的模板,对象是类的实例

         2.一个类可以创建N个对象

         3.每个对象都是独一无二的

         4.对象和类满足is a的关系

类:

      是我们在生活中对身边的事务进行不自觉的分类!在脑海中只是一个定义,生活中不存在,存在的是具体的实例

对象:

       用来描述事物的一个实体,由一组属性和方法构成

       把一组具有相同属性和行为的一些对象,封装成一个类

面向对象的优势:   

        1.与我们的思维方式一致

        2.提高程序的可重用性

        3.隐藏对象的内部细节,提高程序的维护性和安全性

直接写在类中的属性   全局变量,有默认值

           局部变量没有默认值,不赋予初始值不能直接使用

所有的访问权限修饰符:

           1.public   公共的,级别最宽松

           2.protected    受保护的,只能在子类中访问

           3.default    默认的访问权限,没有这个单词,仅限于本包中访问

           4.private   私有的,级别最严的,只能本类中访问 

       访问权限修饰符可以定义在全局变量和方法上

步骤:

       1.创建对象 实例化对象

         类名 对象名=new 类名();//实例化一个对象,调用无参构造

         只要有(),就说明是一个方法

         类名()----构造方法,

         只有构造方法才能构造出一个类的实例

         例: new Student();

                通过构造方法来创建类的实例

                 疑问  在Student类中并没有Student()方法,系统会默认给我们创建类的无参                         构造方法

        2.使用对象的属性和方法

               对象名.属性名

               对象名.方法名

Java中没有指针的概念,示意图中的箭头只是一种比喻,在Java中指针我们称之为引用

       null是所有引用类型的默认值,不能点出来任何内容,只要点出来,就会出现                 NullPointException(空指针异常)

        调用对象某个方法的时候,给方法的东西叫参数

        调用对象的某个方法,返回的东西就是返回值

无参构造:

         访问修饰符+类名===构造方法  用来创建对象的实例

         绝对不允许加返回值

         new 类名();//实例化一个对象,调用无参构造

带参构造:

        目的:在创建对象的同时,给对象的各个属性赋值

         (int age,String name)参数列表

        1.int age,String name形参

        2.必须有数据类型

        3.实参的参数列表和顺序必须和形参一致 

this:当前对象

     this.age=age;将用户传递过来的局部变量赋值给成员变量

      在成员变量和局部变量同名的时候,使用this来区分

项目代码,阅读顺序

       1.bean

       2.test

       3.login

       4.demo

       5.paramater

参数的传递

        1.基本数据类型+String,作为参数传递,传递的都是值

        2.引用数据类型,作为参数传递,传递的内存地址  (数组属于引用数据类型)

对象数组:

        对象类型的数组        

public class Student {
static Scanner input=new Scanner(System.in);
//int age;
String name;
//创建Student类型的数组
Student[] stu=new Student[5];

/**
* 定义一个方法,给数组中的每个对象的属性赋值
*/
public void addStudent(){

for (int i = 0; i < stu.length; i++) {
//实例化数组中的每个元素
stu[i]=new Student();

System.out.println("请输入第"+(i+1)+"个学生的姓名:");
stu[i].name=input.next();
//System.out.println("请输入第"+(i+1)+"个学生的年龄:");
//stu[i].age=input.nextInt();
}
}
/**
* 遍历对象数组中的每个对象的数据
*/
public void showStudent(){
System.out.println("****学生信息如下****");
for (Student s : stu) {
System.out.println(s.name);
}
}
/**
* 修改学生姓名
*/
public void changeName(String oldName,String newName){
boolean flag=false;
for (int i = 0; i < stu.length; i++) {
if(stu[i].name.equals(oldName)){
stu[i].name=newName;
flag=true;
break;
}
}
if(flag){
System.out.println("找到了!");
}else{
System.out.println("没找到!");
}
}
/**
* 查找学生姓名
*/
public void findName(int start,int end,String name){
boolean flag=false;
for (int i = start-1; i < end; i++) {
if(stu[i].name.equals(name)){
flag=true;
break;
}
}
if(flag){
System.out.println("找到了!");
}else{
System.out.println("没找到!");
}
}
public static void main(String[] args) {
//实例化对象
Student student=new Student();
student.addStudent();
//修改学生姓名
System.out.println("请输入您要修改的学生姓名:");
String oldName=input.next();
System.out.println("请输入修改后的学生姓名:");
String newName=input.next();
student.changeName(oldName, newName);
System.out.println("请输入您要查找的初始位置:");
int start=input.nextInt();
System.out.println("请输入您要查找的结束位置:");
int end=input.nextInt();
System.out.println("请输入您要查找的学生姓名:");
String name=input.next();
student.findName(start, end, name);
student.showStudent();
}
}

 shift+alt+s ---overrite implements method--object--toString()

          1.因为Java中所有的类都继承object

          2.如果我们想输出对象,不是看它的内存地址,而是需要看到对象的每个属性值

          3.需要重新object类中的toString()

shift+alt+a:全选

面向对象的三大特性:

          1.封装

             概念:将类的所有信息隐藏起来,不让外部类直接访问,而是通过对应的方法去访问

             目的:隐藏类的内部细节,安全

             步骤:

                1.所有属性私有化

                2.创建对应的get set方法shift+alt+s

                3.在set方法中增加逻辑判断,确保数据的准确性

                所有的get都是取值,所有的set都是给属性赋值

             方法重载:方法=行为  其实就是一个静态的多态

                  1.在同一个类中

                  2.方法名相同

                  3.参数列表不同(个数||类型||顺序)

                  4.与访问修饰符和返回值无关

              static:

                   一个类在被JVM加载的时候,首先会加载类中被static修饰的所有属性,方法,代码块.并把这个static修饰的内容放进静态存储区,便于我们共享访问

                   static修饰的属性和方法叫做类属性和类方法,其他的叫做实例属性和实例方法

                1.static可以修饰

                   1.属性     静态属性

                   2.方法     静态方法

                   3.代码块   静态代码块

                2.static的特点

                    01.static修饰的内容,在整个程序运行期间,只有一份,而且所有对象共享

                           比如说,我们在Student中定义了一个变量,

                                static int age;

                          Student类中创建N个对象,都共享这个 age属性 

                          如果有一个对象更改了age属性的值,其他的N个对象也跟着变化

                    02.静态方法中不能访问非静态属性和静态方法

                          int age;//普通属性

                         public static void sayHello(){

                            System.out.println(age);//编译报错

                         }

                    03.普通的方法中可以访问静态属性和静态方法

                           static int age;//静态属性

                            public void sayHello(){

                               System.out.println(age);

                              }

                     04.静态属性和静态方法可以直接通过类名访问

                         类名.静态属性

                         类名.静态方法

                        比如说:Student类有一个普通方法sayHello(){}

                        我们想调用这个方法?

                          1.实例化对象 Student s=new Student();

                          2.调用方法  s.sayHello();

                       现在sayHello()变成了静态方法,我们怎么访问?

                          1.sayHello()在Student类中,我们无需实例化

                          2.直接访问Student.sayHello()                       

                书写实体类的步骤:

                      1.私有化属性

                      2.快捷键生成set,get方法

                      3.快捷键生成有参和无参构造

                      4.重写toString()

                this注意点:

                      1.this()调用无参构造

                      2.this(……)调用带参构造

                      3.this调用构造方法时,只能出现在构造方法中

                      4.this调用构造方法时,必须位于构造方法中的第一行

                      5.this访问对象的属性或者方法的时候,可以出现在任何方法中

          2.继承(extends)

             Object是所有java类的父类

             super()调用父类的无参构造,无论有没有显式调用父类的无参构造,都会调用父类              的无参构造,如果没有调用父类的带参构造,会先执行父类的无参构造,再执行子类              的带参构造

            注意:

             (1.如果我们实例化子类对象的时候,调用的是无参构造,会先调用父类的无参构造

              2.如果我们实例化子类对象的时候,调用的是带参构造,但是在构造方法中没有显                   式的输出super(参数),默认会先调用父类的无参构造

              3.如果我们实例化子类对象的时候,调用的是带参构造,在构造方法中显式的输出                super(参数),默认会先调用父类的带参构造)

             1.无论子类是否显示的调用super,都会先调用父类的无参构造,除非显示调用父类               的带参构造

             2.父类中私有的属性或者方法,子类不能继承

             3.父类的构造方法,子类也不能继承

           super关键字:

             1.只能出现在子类的方法中

             2.如果调用父类的构造方法,只能出现在子类的第一句

             3.super.属性  调用父类的属性

                super.方法   调用父类的方法

             重写的注意事项:

                1.有继承关系

                2.不在一个类中,子类重写父类的方法

                3.方法名一致,参数列表一致

                4.重写方法的访问权限修饰符不能严于父类

                5.父类中的静态方法不允许被重写,子类中可以创建同名的静态方法,跟父类的                    无关  

                6.父类的私有方法不允许被重写

                7.如果父类的方法有返回值,子类重写的时候,可以返回这个值的本身或者是返                    回值的子类型

                子类和父类满足is a的关系

                单根性:一个类只能有一个直接的父类

                equals:

                    (基本数据类型比较的是值,引用数据类型比较的是内存地址)

                    1.为什么String类中的equals是比较的字符串内容

                         01.查询Object类中的方法                          

                                                                           public boolean equals(Object obj) {
                                               return (this == obj);
                                                                             }//比较的是内存地址

                                  02.再去看String类中的方法

                             String中的equals是重写了Object类中的equals方法,比较的是内                              容

                     String a="abc";

                     String b="abc";

                     String c = new String("abc");

                     System.out.println(a.equals(b)); // 值肯定一致 所以返回 true

                     System.out.println(a == b);// 内存地址也一致 所以 true

                     System.out.println("****************************************");

                     System.out.println(a.equals(c));// 值肯定一致 所有返回 true

                     System.out.println(a == c);// 内存地址不一致 所以 false

                     String a = "a";
                     String b = "bc";
                     String c = "abc";
                     System.out.println(c == ("a" + "bc")); //true

                     01.在程序编译期间 会把常量(不变)a 和常量bc 合并成 abc
                     02.之后再和“abc“进行比较

                     String a = "a";
                     String b = "bc";
                     String c = "abc";
                     System.out.println(c == (a + b)); // false

                     01. a 和 b 都是变量(变化), 在编译期间无法确定变量的值
                     02. c在编译期间已经确定, ab无法确定

                    final String a = "a";
                    final String b = "bc";
                    String c = "abc";
                    System.out.println(c == (a + b)); // true

                 final可以修饰:

                    1.修饰的属性,就是常量,运行期间不能改变

                    2.修饰的方法,不能被子类重写

                    3.修饰的类不允许被继承

         

               例子: Student类和Teacher类都继承Person

                 1.如果 Student类和Teacher类都没有去重写父类的sleep方法,name调用sleep                    方法的时候,都是输出同样的语句

                 2.让子类去重写父类的sleep方法(子类一旦重写了这个sleep方法,当前父类                      的这个方法有存在的意义,但是方法中的内容<方法体>没有存在的意义!因为                    Person的子类会去重写这个方法

                    01.去掉方法体之后发现编译错误,

                    02.鼠标放在错误位置出现两种选择

                          001.add body     X

                          002.add abstract   

                                                     03.在方法上面增加了abstract 之后,还是报错,鼠标放在错误位置,出现两                         种选择

                             001.remove abstract      X

                             002.make type Person abstract                     

)    

                  abstract: 一个方法的声明处出现了abstract关键字----抽象方法

                   1.抽象方法必须位于抽象类中

                   2.抽象方法没有方法体

                   3.必须被子类重写,除非子类也是抽象类

                 由abstract修饰的类就是抽象类

                  1.抽象类可以有普通方法

                  2.抽象类不能被实例化,但是可以有构造方法

              3.多态

                 之前的练习中,使用过方法重载

                 方法名一致,代表的是同一个行为

                 参数列表不一致,代表的是行为所需要的参数不一致

                  得到的结果也不一样

                程序中的多态

                   1.静态的多态    方法重载(程序在编译期间,就已经确定了需要执行的方法)

                   2.动态的多态    程序在运行期间才能确定需要执行什么方法

                   同一个引用类型(父类),使用不同的对象实例(子类),执行一个相同的操作,                    但是得到不同的结果

                 多态存在的必要条件

                    1.要有继承

                    2.要有重写

                    3.向上转型  父类引用指向子类对象(指针泛化)

                 多态的实际应用:

                      1.使用父类作为方法的参数

                      2.使用父类作为方法的返回值

接口

      案例:1.小猫小狗都有一个共同的属性

            2.提取一个Animal类

            3.小猫小狗等其他动物都有吃饭的方法

            4.所有在Animal类定义一个eat()方法

            5.每个动物吃的食物不同,所以Animal的eat()方法不能有方法体

            6.Animal变成了抽象了

       加了一个动物----小鸟

          7.小鸟会飞

          8.如果把fly()放进Animal里面,不可行,所有的动物都会飞了

          9.航天器,飞机……等都会飞

          10.如果我们在每个类中都去书写fly()方法,也不行

          11.引入接口(具有某种能力<has a>------>>实现implements接口Interface)

          我们生活中发现一些对象具有相同的特征和行为,我们提取成类 class

          类中有相同的属性和方法,称为父类superclass

          如果父类中的方法没有实现的意义,那么这个类就叫做抽象类abstract

          如果某个子类有特殊的功能,就使用接口interface

接口的特点:

        1.所有的方法都是抽象方法,不允许有普通方法

        2.接口的方法必须被实现类实现,除非实现类是抽象类或者接口

        3.接口中所有的变量都是静态常量,必须赋予初始值(Ctrl+shift+x/y 大小写)

        4.接口解决了Java中单根继承的问题,一个类可以实现N个接口

        5.类继承父类,实现接口,

         一个接口可以继承N个接口

       6.接口也不允许被实例化,也不允许有构造方法

接口的类型:

       1.大多都是方法

       2.大多都是属性

       3.什么也没有

内部类:每个内部类都会单独生成一个.class文件

     把一个类写在了另外一个类或者方法中

外部类必须是public修饰的,不能更改访问权限修饰符,内部类可以设置访问权限修饰符

内部类的分类:

      1.成员内部类  直接定义在外部类的内部

         使用成员内部类:

           1.实例化外部类对象

           2.通过外部类对象创建内部类对象

           3.调用内部类的属性和方法

             Father father=new Father();

             Father.Son son=father.new Son();

             son.sayHello();

       特点:

          1.可以拥有private,protect访问权限修饰符

          2.如果外部类和内部类属性重名,默认使用内部类

              想使用外部类的属性 外部类名.this.属性/方法名

                "外部类的age"+Father.this.age

          3.想访问内部类,必须先创建外部类对象

      2.局部内部类   被定义在某个方法或者代码块中,仅限于所属的方法内使用

            1.仅限于方法体内使用(局部变量)          

      3.匿名内部类

             1.没有名称,看不到类的定义

             2.所有的匿名内部类必须继承一个类或者实现一个接口

             3.如果匿名内部类中需要外部的参数,这个参数必须是final修饰

      4.静态内部类

             1.成员内部类加上static

             2.不依赖于外部类,可以直接创建对象

/**
* 访问静态内部类
*/
Son2 son2=new Son2();
son2.sayHello();

             3.不能访问外部类非静态的属性和方法

异常:

      程序在运行期间发生了不可预测的事件,阻止了程序的正常运行

   异常的处理机制:在我们程序发生异常之后,代码能够按照我们事先设计的顺序  继续执行!   

     异常的分类:

           所有异常和错误的父类------>>Throwable

           1.运行时异常    RunTimeException

             ArithmeticException                 算术异常

             ArrayIndexOutOfBoundsException   数组下标越界

             NullPointerException                空指针异常

             InputMisMatchException              数据类型不匹配

             ClassCastException                   对象强制类型转换

             NumberFormatException                数字格式转换异常

           2.受查异常      CheckedException  IOException

     异常的使用

          try catch finally throw throws

          异常的处理分为两种方法 

            1.try catch finally

               try

              01.不能单独使用,必须和catch /finally连用

              02.代码块中存放可能出现异常的代码

              03.如果try代码块中出现了异常,会去匹配catch代码块对应的异常类型,没有匹                  配的类型的时候,直接进入finally

               catch

              01.可以有多个catch块,每个catch都能捕获一个异常

              02.多个catch块捕获的异常类型不允许重复

              03.多个catch块的异常类型必须是从小到大排列

              04.如果多个catch块都能匹配,默认使用第一个匹配的

              05.如果try中都没有发生异常,catch代码块被忽略

              06.每个代码块中的变量都是私有的

                finally

              01.无论异常是否发生,代码块都会执行

              02.如果遇到了System.exit(0);或者System.exit(非0),不会执行finally代码块

              03.如果try代码块出现了return,先执行finally再跳出方法

              04.后续关闭流,释放数据库链接资源

            2.throw抛出异常  throws声明异常

              throw抛出异常

                01.语法throw new 异常类型(异常信息)

                02.异常类型必须是Exception或者其子类

                03.一个throw只能抛出一个异常

                04.throw只能出现在方法体内

                05针对于抛出的异常,有两种方式解决

                   001.try catch finally

                   002.throws

                06.抛出异常的类型必须是声明异常类型本身或者是其子类类型

            throws声明异常

              01.语法 throws 异常类型1,异常类型2……

              02.定义在方法的参数列表之后,可以声明多个异常

              03.throws不是处理异常,是声明异常,方法的调用者去处理异常

              04.如果在main方法中使用throws,则是jvm来处理异常

     异常链的使用:

         把我们捕获的异常包装成一个新的异常,继续抛出,新异常中记录了异常的原始信息

         便于找到异常的根本原因

            // main方法
            public static void main(String[] args) {
                try {
                       firstException();
                     } catch (SQLException e) {
                         e.printStackTrace();
                     }
                  }

           // 第1个异常
            private static void firstException() throws SQLException {
                 try {
                       secondException();
                      } catch (IOException e) {
                         e.printStackTrace();
                         throw new SQLException("第1个异常", e);
                      }
                   }

          // 第2个异常
           private static void secondException() throws IOException {
              try {
                      thirdException();
                    } catch (InputMismatchException e) {
                         e.printStackTrace();
                         throw new IOException("第2个异常", e);
                       }
                    }

          // 第3个异常
          private static void thirdException() throws InputMismatchException {
                throw new InputMismatchException("根本的异常");
          }

     自定义异常:

          1.异常类必须是Throwable的子类

          2.自定义异常类继承RuntimeException,Exception

                  /**
                   * 针对于Student的异常类
                   */
                   public class StudentException extends Exception {

                       public StudentException(String msg) {
                             super(msg);
                        }

                      public StudentException(String msg, Throwable e) {
                          super(msg, e);
                        }

                      }

                   /**
                     * 针对于AgeException的异常类
                     */

                        public class AgeException extends StudentException {

                           public AgeException() {
                             super("年龄异常");
                              }

                          }

                   /**
                     * 针对于NameException的异常类
                     */

                  public class NameException extends StudentException {

                    public NameException() {
                      super("姓名异常");
                      }

                     }

                                     /**
                     * StudentDemo测试类
                     */

                     public class StudentDemo {

                          public static void main(String[] args) throws StudentException {

                              Scanner input = new Scanner(System.in);
                              System.out.println("请输入异常(age/name)");
                              String answer = input.next();
                                if (answer.equals("age")) {
                                  throw new AgeException();
                                  } else if (answer.equals("name")) {
                                        throw new NameException();
                                   } else {
                                      createStudent();
                                   }

}

private static void createStudent() throws StudentException {
throw new StudentException("学生创建异常");
}

}

     

原文地址:https://www.cnblogs.com/s10-/p/7941549.html