微信公众号开发 远程桌面登陆 微信小程序 整数转换 Jetson Nano golang postgresql knockoutjs loam算法测试 orm Animsition vue异步加载组件 jquery遍历对象 docker的安全特性有哪些 python函数参数 python数字类型 java的包 javaif语句 java开发学习 javarandom java语言是什么 linux目录系统 键盘宏软件 笔记本外接显示器好吗 华为线刷工具 三维看图软件 数科阅读器 编程语言实现模式 adobe卸载工具 视频编辑专家下载 xapk安装器 任意屏官网 小程序游戏源码 jsp源代码 vc运行库合集 网易云听歌识曲电脑版 cdr怎么填充颜色 画吧教程 dns地址 冲击波专杀
当前位置: 首页 > 学习教程  > 编程语言

Java入门学习笔记(六)

2020/8/11 19:48:00 文章标签:

面向对象编程(OOP)

面向对象编程的本质:分类的思维方法,首先思考需要哪些分类,最后对分类下的细节进行面向过程的思索。适合处理复杂的问题。以类的形式组织代码,以对象的组织(封装)数据。

IDEA添加out目录
Project structure—>Modules—>Add content root—>项目所在文件夹—>out。

构造器

规则

  • 必须和类的名字相同。
  • 必须没有返回类型,也不能写void。

作用
使用new关键字,本质是在调用构造器。
用来初始化值。

注意点
定义了有参构造,如果想使用无参构造,必须定义无参构造。

封装

“高内聚,低耦合”:累的内部细节自己完成,不允许外部干涉,仅暴露少量方法给外部使用。
属性私有,get/set

  • 提高代码安全性,保护数据
  • 隐藏代码实现细节
  • 提高可维护性

继承

继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
java中只有单继承,没有多继承。

继承注意点

  • 子类默认调用父类的无参构造。
  • 父类如果有有参构造,子类可通过调用父类的有参构造继承父类,如有子类需要调用父类的无参构造,父类必须定义无参构造。
  • java中所有类默认继承object类

super注意点

  • super()调用父类的构造方法,必须在构造方法的第一个。即子类构造器的第一句是super();。
  • super必须只能出现在子类的方法或者构造方法中。 super和this不能同时调用构造方法。即不能同时出现在子类构造器中。

VS this
代表的对象不同:
this:对象本身。
super:父类对象的引用。

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

构造方法:
this():本类的构造。
super():父类的构造。

重写

重写(override)都是方法的重写,和属性无关。
需要有继承关系,子类重写父类的方法!(而不是属性)

  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符:范围可以扩大但不能缩小,public>protected>default>private
  • 抛出的异常:范围,可以缩小,但不能扩大

重写,子类的方法和父类必须要一致,方法体(即里面的代码)不同。

为什么需要重写:

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

静态方法:方法调用只和对象的类型的有关,例:

//A是B的子类,test()是静态方法
B b = new A();
b.test();

此时调用的是类B内的test()方法。

非静态:此时将方法重写,例:

//A是B的子类,test()是非静态方法
B b = new A();
b.test();

此时父类B中的test()方法已被A类重写。

故方法重写只与非静态方法有关。

多态

  • 多态是方法的多态,属性没有多态
  • 父类和子类有联系,类型转换异常 ClassCastexception

同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的的引用的类型有很多(父类,有关系的类)

存在条件

  • 有继承关系
  • 子类重写父类方法
  • 父类引用指向子类对象

多态注意事项

不能重写的方法:

  • static 方法,属于类,不属于实例;
  • final 常量;
  • private方法

类型转换

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

  • 父类引用指向子类的对象。
  • 把子类转换为父类,向上转型,无需强制转换,但会丧失子类特有的方法.
  • 把父类转换为子类,向下转型,强制转换。
  • 方便方法的调用,减少重复的代码

static详解

非静态方法可以访问静态方法;
静态方法只能调用静态方法。
原因是类的加载顺序,静态方法随着main一起加载。

静态变量调用

public class Student {
        private static int age;
        private double score;
  
  public static void main(String[] args) {
            Student s1 = new Student();
            System.out.println(Student.age);//静态变量通常使用这种调用方法
            System.out.println(s1.age);
            System.out.println(s1.score);//必须new之后才能调用
        }

代码块

public class Student {
        private static int age;
        private double score;
    {
        //匿名代码块
        System.out.println("匿名代码块");
    }
    
    static{
            //静态代码块,首先被执行,只执行一次
            System.out.println("静态代码块");
    }

    public Student() {
        System.out.println("构造方法");
    }

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

输出:

静态代码块
匿名代码块
构造方法
=================
匿名代码块
构造方法

解释:静态代码块,首先被执行,只执行一次。匿名代码块在构造方法前执行。

静态导入包

import static java.lang.Math.random;

public class Demo01 {
    public static void main(String[] args) {
        System.out.println(random());
    }
}

此时可以直接调用random方法。

注意:final类不能被继承。

抽象类

abstract 抽象类,只能单继承。(接口可以多继承)

public abstract class Action {
    public abstract void doSomething();
}

抽象方法
约束,有人去实现

  • 只有方法名,没有方法的实现
  • 不能new这个抽象类,只能靠子类去实现它
  • 抽象类中可以写普通的方法
  • 抽象方法必须在抽象类中
  • new抽象类的子类后,该抽象类有构造器。

抽象类存在的意义:提高开发效率。

接口

声明关键字:interface
接口就是规范,定义的是一组规则
接口中的所有定义其实都是抽象的

注意点

  • 约束 定义一些方法,让不同的人去实现
  • 方法的类型都是public abstract
  • 常量的类型都是public static final
  • 接口不能被实例化,接口内没有构造方法
  • implements可以实现多个接口
  • 必须要重写接口中的方法
//userService.java
public interface userService {
    //接口中定义的是常量,public static final
    int AGE=99;
    
    //接口中定义的所有方法都是是抽象的,默认是public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
timeService.java
public interface timeService {
    void timer();
}
//userServiceImpl.java
//类可以实现接口 implements 接口名称
//实现接口的类,需要重写接口中的方法
//利用接口实现多继承
public class userServiceImpl implements userService,timeService{
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {
    }
}

N种内部类

成员内部类

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: "+id);
            }
        }
}
//一个java文件中可以有多个class类,但是只能有一个public class
class A{
}
public class test extends Outer{
    public static void main(String[] args) {
        Outer out = new Outer();
        //通过外部类来实例化内部类
        Outer.Inner inner=out.new Inner();
        inner.getID();
    }
}

输出:

Id: 10

静态内部类

public class Outer {
        static private int id=10;
        public void out(){
            System.out.println("这是外部类的方法");
        }
        public static class Inner{
            public void in(){
                System.out.println("这是内部类的方法");
            }

            //此时id会报错,这是由于id不是静态常量,将id前修饰符加上static即可
            public void getID(){
                System.out.println("Id: "+id);
            }
        }
}
public class test extends Outer{
    public static void main(String[] args) {
        Outer out = new Outer();
        //通过外部类来实例化内部类,此时直接将Inner类实例化即可
        Inner inner=new Inner();
        inner.getID();
    }
}

局部内部类

public class Outer {
       publid void method(){
       //局部内部类,不建议这样用
       class A{      
       }
    }
}

匿名内部类

public class test extends Outer{
    public static void main(String[] args) {
        //没有名字初始化类,不用将实例保存到变量中
        new Apple().eat();
        new UserService(){
            @Override
            public void Hello() {
            }
        };
    }
}

class Apple{
    public void eat(){
        System.out.println("eat");
    }
}

interface UserService{
    void Hello();
}

异常机制

error一般是程序无法控制和处理的,jvm一般会选择终止线程;exception通常是可以被处理的,程序尽可能处理这些异常。

异常处理5个关键字

  • try
  • catch
  • finally
  • throw
  • throws

捕获异常

public class test {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        //windows中crtl+alt+t快捷生成try
        //Mac中Command+option+t快捷生成try
        try { //try监控区域
            new test().divide(a, b);
        }catch (Error e){//捕获异常,括号内为想要捕获的异常类型
            System.out.println("Error,b不能为0");
        }
        catch (Exception e){//捕获异常,括号内为想要捕获的异常类型
            System.out.println("Exception,b不能为0");
        }
        catch (Throwable e){//捕获异常,括号内为想要捕获的异常类型
            System.out.println("Throwable,b不能为0");
        } finally{//处理善后工作
            System.out.println("finally");
        }
    }
        public void divide ( int a, int b){
            System.out.println(a / b);
        }
}

输出:

Exception,b不能为0
finally

主动抛出异常

public class test {
    public static void main(String[] args) {
        try {
            new test().divide(1,0);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        } finally {
            System.out.println("程序异常,b不能为0");
        }
    }
    //假设在这个方法,处理不了这个异常。方法上抛出异常用throws
    public void divide(int a, int b) throws ArithmeticException{
       if (b==0){//方法内抛出异常用throw
           System.out.println("程序异常,divide抛出异常");
           throw new ArithmeticException();//主动抛出异常,一般在方法中使用
       }
    }
}

输出:

程序异常,divide抛出异常
java.lang.ArithmeticException
	at demo.Demo17_oop_exception.Test.divide(Test.java:58)
	at demo.Demo17_oop_exception.Test.main(Test.java:10)
程序异常,b不能为0

自定义异常

//MyException.java
public class MyException extends Exception{
     private int detail;
     public MyException(int a){
         this.detail=a;
     }
     //toString:异常的打印信息
    @Override
    public String toString() {
        return "MyException{" + detail + '}';
    }
}
//test.java
public class test {
    public static void main(String[] args) {
        try {
            test(1);
            test(11);
            test(5);
        } catch (MyException e) {
            System.out.println("MyException==>"+e);
        }
    }
    //可能会存在异常的方法
    static void test(int a) throws MyException{
        System.out.println("传递的参数为: "+a);
        if(a>10){
            throw new MyException(a);//抛出异常
        }
        System.out.println("OK");
    }
}

输出:

传递的参数为: 1
OK
传递的参数为: 11
MyException==>MyException{11}

test(5)未运行,这是由于test(11)抛出异常后,被catch捕获,跳过test(5)。

实际应用中的经验总结

  • 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
  • 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
  • 对于不确定的代码,也可以加上try-catch,处理潜在的异常
  • 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出 具体如何处理异常,要根据不同的业务需求和异常类型去决定
  • 尽量添加finally语句块去释放占用的资源

参考博客


本文链接: http://www.dtmao.cc/news_show_100192.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?