疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java基础学习笔记与总结


 

 
title: java面向对象
 
categories: Java
 
方法的定义、方法的重载、方法的递归调用。
类的定义、 类的声明、类的使用
方法
方法的定义
 
方法就是一段可以重复的代码段。
 
访问修饰符 返回值类型 方法名(){
        方法主体
}
方法的重载
 
方法名称相同。但是参数的类型和个数不同,通过传递参数的个数和类型不同来完成不同的功能。
 
public void tell(int i){
    
public void tell (int i,int y){
    
}
方法的返回值类型,void类型不需要返回值,其他的类型都需要返回值。
 
方法的递归调用
 
一种特殊逇调用方式,就是方法自己调自己。
 
类的定义
 
类是对某一事物的描述,是抽象的。概念上的意义,对象是实际存在的该类事物的每一个个体,也被称为对象或实例。
 
类的声明
 
class Person{
    public String name;
    public int age;
    public void tell() {
        System.out.println("姓名:"+name+",年齡:"+age);
    }
}
类的使用
 
public static void main(String[] args) {
        Person person;//声明对象,开辟栈内存空间
        person=new Person();//开辟堆内存空间
        person.name="张三";
        person.age=10;
        person.tell();
    }
通过关键字 new 开辟空间,实例化操作。
 
Yavviy
 
面向对象的三大特征
封装性
 
对外不可见。保护某些属性和方法不被外部所看见。
 
封装的实现:为属性和方法进行封装是通过关键字private声明的,实现该属性的set和get方法,为外部所访问。
 
class Person{
    private int age;
 
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void tell() {
        System.out.println("年龄:"+getAge());
    }
}
public class PrivateDemo01 {
    public static void main(String[] args) {
        Person person=new Person();
        person.setAge(160);
        person.tell();
    }
 
}
继承
 
扩展类的功能。可以说为:扩展父类的功能。
 
继承的实现
 
java中使用 extends 关键字完成继承
 
    class 子类 extends 父类 {
 
    }
继承的限制
 
在java 中只允许单继承 (一个儿子只能有一个亲生父亲)
 
子类不能直接访问父类的私有成员,那么如何进行访问父类的私有成员呢?需要子类实现get(),set()方法去进行访问。
 
class People {                      //新建一个People类
    private int age;                //封装属性
    public int getAge() {           //实现age属性的getAge(),setAge()方法。
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
public class ExtendsDemo01 {
    public static void main(String[] args) {
        Worker worker=new Worker(); //实例化worker对象。
        worker.setAge(100);         //用setAge()方法设置worker的age属性。
        System.out.println(worker.getAge());//用getAge()方法进行获取worker的age值。
    }
}
 
子类对象的实例化过程
 
在子类对象实例化之前,必须先调用父类中的构造方法,之后调用子类构造方法。
 
class Father{                       //新建一个People类
    private int age;                //私有age属性
    private String name;            //私有name属性
    public Father(){                //构造方法
        System.out.println("父类的构造方法");
    }
}
class Son extends Father{           //新建Son类继承与Father
    public Son() {
        System.out.println("子类的构造方法");
    }
}
public class ExtendsDemo02 {
    public static void main(String[] args) {
        Son son=new Son(); //实例化Son子类。构造方法不需要进行调用,直接实例化.
    }
}
 
 
方法的重写
 
在继承中,也存在着重写的概念。其实就是子类定义了父类同名的方法。
 
定义:方法名称相同,返回值类型相同,参数也同。
 
重写限制:被子类重写的方法不能拥有比父类更加严格的访问权限 (private<default<public)。
 
class A {
    public void tell(int a) {   //创建tell方法
        System.out.println("我tell方法");
    }
    void say(){
        System.out.println("我创造default的say方法");
    }
}
class B extends A {
    public void tell(int a) {   //子类也创建tell方法(即为重写)
        super.tell(10);         //若要调用父类的方法,可以用super关键字来调用
        System.out.println("我重写tell方法");
    }
}
public class ExtendsDemo03 {
    public static void main(String[] args) {
        B b = new B();
        b.tell(10);
    }
}
    void say(){
    System.out.println("我的权限只能是default");  //不能修改为比父类更低的访问权限,例如修改为 private void say(){}
}
super关键字
 
强行调用父类的方法的执行
 
super不一定在重写中使用,也可以表示那些方法时从父类中继承而来的。
 
重写与重载的区别
 
No 区别点 重载 重写
1 单词 Overloading Overriding
2 定义 方法名称相同,参数类型或个数不同 方法名称、参数的类型、返回值类型全部相同
3 权限 对权限没有要求 被重写
4 范围 发生在一个类中 发生在继承中
多态性
 
方法的重载,对象的多样性。
 
常见异常
数组越界异常
 
ArrayIndexOutOfBoundsException
 
数组格式化异常
 
NumberFormatException
 
算数异常
 
ArithmeticException
 
public class Exception {
    public static void main(String[] args) {
        int a=10;
        int b=0;
        int temp=0;
        try {
            temp=a/b;
        } catch (ArithmeticException e) {
            System.out.println("除数不能为0");
        }
    }
}
空指针异常
 
NullPointerException
 
构造方法
访问修饰符 类名称(){
    程序语句
}
注意点:
 
1.构造方法名称必须与类名一致。2.构造方法没有返回值。
 
构造方法主要是为类中的属性初始化
 
每个类在实例化之后都会调用构造方法,如果没有构造方法,程序在编译的时候回创建一个无参的什么都不做的构造方法
 
构造方法可以重载
 
class People{
    int age;
    String name;
    public People(int a,String n) {
        age=a;
        name=n;
        System.out.println("姓名:"+name+",年龄:"+age);
    }
    public People(int a) {
        age=a;
        System.out.println("年龄:"+a);
    }
}
public class ClassDemo02 {
    public static void main(String[] args) {
        People people=new People(30,"小米");//构造方法
        new People(23);
    }
}
引用传递
class Ref1 {
    int temp = 10;
}
 
public class RefDemo01 {
 
    public static void main(String[] args) {
        Ref1 ref1 = new Ref1();
        ref1.temp = 20;
        System.out.println(ref1.temp);
        tell(ref1);
        System.out.println(ref1.temp);
    }
 
    public static void tell(Ref1 ref2) {
        ref2.temp = 30;
    }
}
this 关键字
表示类中属性和调用方法
 
调用本类中的构造方法
 
表示当前对象
 
class People {
    private String name;
    private int age;
 
    public People(String name, int age) {
        this();
        this.name = name;
        this.age = age;
 
    }
 
    public People() {
        System.out.println("无参构造方法");
    }
 
    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;
    }
 
    public void tell() {
        System.out.println("姓名:" + this.getName() + "年龄:" + this.getAge());
    }
}
 
public class ThisDemo {
 
    public static void main(String[] args) {
        People people = new People("张三", 30);
        people.tell();
    }
 
}
 
static 关键字
使用 static 声明属性
 
static声明全局属性
 
使用static声明方法
 
直接通过类名调用
 
注意点:使用 static 方法的时候,只能访问 static 声明的属性和方法,而非 static 声明的属性和方法是不能访问的。
 
final关键字
final关键字在java中称为完结器,表示最终的意思
final能声明类、方法、属性.
使用final声明的类不能被继承
 
使用final声明的方法不能被重写
使用final声明的变量变成常量,常亮是不可以被修改的。
抽象类
概念:包含一个抽象方法的类。
定义格式: abstract class ClassNmae{ 属性 方法 抽象方法 }
抽象方法:声明而未被实现的方法,抽象方法必须使用abstract关键字方法。
抽象类不能直接实例化
抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有的抽象方法。
```
abstract class Abs { // 抽象类
private int age; // 私有成员变量
 
public void tell() {
 
}
 
public abstract void say(); // 抽象方法
 
public abstract void print();
 
public void setAge(int age) { // 访问父类私有成员变量,只能通过实现set()和get()方法
this.age = age;
}
 
public int getAge() {
return age;
}
}
 
class AbsDemo extends Abs { // 子类AbsDemo继承Abs,
public void say() {
System.out.println(getAge());
}
 
public void print() {
 
}
}
 
public class AbstractDemo01 {
 
public static void main(String[] args) {
    AbsDemo absDemo = new AbsDemo(); // 实例化子类
    absDemo.setAge(30);
    absDemo.say(); // 子类AbsDemo必须重写抽象类中所有的抽象方法
    absDemo.print();
 
}
}
```
 
接口
接口可以理解为一种特殊的类,里面全部是由全局变量和公共的抽象方法所组成。是Java中最重要的概念。
接口的格式:
 
    interface interfaceName{
            全部变量
            抽象方法
        }
接口的实现也必须通过子类,使用关键字implements,而且接口可以多实现的。
 
一个子类也可以同时继承抽象类和实现接口。
 
一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口。实现接口的多继承。
 
interface Inter1 {
public static final int AGE = 100;
 
public abstract void tell();
}
interface Inter2 {
public abstract void say();
}
 
interface Inter3 extends Inter1, Inter2 { // 接口多实现
 
}
 
abstract class Abs1 {
public abstract void print();
}
 
class A extends Abs1 implements Inter1, Inter2 { // 一个子类可以同时继承抽象类,以及多个接口。
public void tell() {
}
 
public void say() {
    System.out.println("我吃");
}
 
public void print() {
 
}
}
 
public class InterDemo01 {
 
public static void main(String[] args) {
    A a = new A();
    a.tell();
    System.out.println(Inter1.AGE);
    a.say();
    a.print();
}
}
```
 
对象接口的使用
 
interface USB {         //创建一个USB接口
    void start();
 
    void stop();
}
 
class C {               //创建一个类
    public static void wrok(USB usb) {      //静态方法,传递USB参数
        usb.start();
        System.out.println("工作中");
        usb.stop();
        System.out.println("");
    }
}
 
class USBisk implements USB {   //创建U盘的类,实现USB接口
 
    public void start() {       
        System.out.println("U盘开始工作");
    }
 
    public void stop() {
        System.out.println("U盘停止工作");
    }
 
}
 
class Printer implements USB {  //创建打印机的类,实现USB接口
 
    public void start() {
        System.out.println("打印机开始工作");
    }
 
    public void stop() {
        System.out.println("打印机开始工作");
    }
 
}
 
public class InterDemo02 {
 
    public static void main(String[] args) {
        C.wrok(new USBisk());   //每个类只是用一次,匿名对象方法调用
        C.wrok(new Printer());
    }
 
}
# 多态性
 
多态性的体现
方法的重载和重写
对象的多态性
对象的多态性
向上转型:程序会自动完成
父类 父类对象=子类实例
向下转型:强制类型转化
子类 子类对象=(子类)父类实例
先发生向上转型,在发生向下转型
instanceof 关键字
在java中可以使用 instanceof 关键字判断一个对象到底是不是一个类的实例
泛型
泛型是在jdk1.5之后新增的功能,泛型(Generic)
泛型可以解决数据类型的安全性问题,他主要的原理,是在类声明的时候通过一个标识表示类中某个属性 的类型或者是某个方法的返回值及参数类型。
格式:
 
访问权限 class 类名称<泛型,泛型。。。>{
属性
方法
}
对象的创建 
> 类名称<具体类型> 对象名称=new 类名称 <具体类型>();
class Point<T>{
    private T x;
    private T y;
    public T getY() {
        return y;
    }
    public void setY(T y) {
        this.y = y;
    }
    public T getX() {
        return x;
    }
    public void setX(T x) {
        this.x = x;
    }
}
 
public class GenericDemo {
    public static void main(String[] args) {
        Point<String>point=new Point<String>();
        point.setY("精度为:100");
        point.setX("精度为:200");
        System.out.println(point.getX()+point.getY());
    }
}
 
构造方法使用泛型
构造方法中使用泛型:
构造方法可以为类中的属性初始化,那么如果类中的属性通过泛型指定,而又需要通过构造方法设置属性内容的时候,那么构造方法的定义与之前并无不同,不需要像声明类那么指定泛型
设置多个泛型
设置多个泛型直接在<>中添加多个泛型就可以了
class Gen<K,T>{
    private T take;
    private K key;
    public T getTake() {
        return take;
    }
    public void setTake(T take) {
        this.take = take;
    }
    public K getKey() {
        return key;
    }
    public void setKey(K key) {
        this.key = key;
    }
    
}
public class GenericDemo02 {
 
    public static void main(String[] args) {
        Gen<String,Integer>gen=new Gen<String,Integer>();
        gen.setTake(10);
        gen.setKey("我是key");
        System.out.println(gen.getKey()+gen.getTake());
        
    }
 
}
在使用泛型方法的时候,也可以传递或返回一个泛型数组
public class CenericDemo07 {
 
    public static void main(String[] args) {
        String arr[]= {"nihao","nihaoya","nizhidao"};
        tell(arr);
    }
    public static <T>void tell(T arr[]){
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}
Java 集合
集合可以理解为一个动态的对象数组,不同的是集合中的对象内容可以任意扩充
集合的特点
 
性能高
容易扩展和修改
Collection接口
 
常用子类:List、Set、Queue
List接口
 
List接口可以存放任意的数据,而且在List接口中内容是可以重复的
List接口常用子类:ArrayList、Vector
 
public class ListDemo01 {   //ArrayList的使用
 
    public static void main(String[] args) {
        List<String> lists = null;
        lists = new ArrayList<String>();
        lists.add("A");   //添加元素
        lists.add("B");
        for (int i = 0; i < lists.size(); i++) {  //通过for循环打印集合所有数据
            System.out.println(lists.get(i));
        }
    }
 
}
List 常用操作:
 
判断集合是否为空:blooean isEmpty()
查找指定的对象是否存在:int indexOf(Object o)
    lists.remove(0);    //移除索引为0的元素
    System.out.println("删除之后------");
    for (int i = 0; i < lists.size(); i++) {
            System.out.println(lists.get(i));    //打印集合中所有元素
        }    System.out.println("集合是否为空?"+lists.isEmpty());
    System.out.println("查找对象是否存在:"+lists.indexOf("B"));     //显示当前元素的索引位置
ArrayList与Vector比较
 
比较 ArrayList Vector
推出时间 JDK1.2之后推出 JDK1.0推出
性能 采用异步方式,性能高 采用同步处理方式,性能低
线程安全 属于非线程安全 属于线程安全
Set接口
 
Set接口不能加入重复元素,但是可以排序
Set接口常用子类
 
散列存放:HashSet
有序存放:TreeSet
public class SetDemo01 {
 
    public static void main(String[] args) {
        Set<String>set=null;
        // HashSet实现,散列存放
        /*
        set=new HashSet<String>();
        set.add("A");
        set.add("B");
        set.add("C");
        set.add("D");
        set.add("E");
        set.add("F");
        System.out.println(set);
        */
        // TreeSet实现,有序存放
        set=new TreeSet<String>();
        set.add("A");
        set.add("B");
        set.add("C");
        set.add("D");
        set.add("E");
        set.add("F");
        System.out.println(set);
    }
 
}
Iterator接口
 
集合输出的标准操作: 标准做法,使用Interator接口
操作原理: Iterator是专门的迭代输出接口,迭代输出就是将一个个进行判断,判断其是否有内容,如果有内容则把内容取出。
public class IteratorDemo01 {
 
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");
        list.add("F");
        Iterator<String> iterator = list.iterator();
 
        while (iterator.hasNext()) {
            String string = iterator.next();
            if ("A".equals(string)) {    //移除A元素
                iterator.remove();
            } else {
                System.out.println(string);
            }
 
        }
    }
 
}
Map接口
 
file类
文件的创建,删除,重命名。
在eclipse中,敲入下方源码,alt+鼠标左键,可以查看file类源代码,方法名称等。
../ 代表上级目录,../../ 代表上级上级目录
当前文件是否为文件:file.isFile()
当前文件的路径:file.isDirectory()
删除文件:file.delete();
创建文件:file.createNewFile();
文件是否存在:file.exists()
重命名方法:file.renameTo();
创建文件夹:folder.mkdir(); 只能创建一级文件夹
创建多级文件夹:folder.mkdirs();
public class FileDemo01 {
 
    public static void main(String[] args) {
        File file = new File("../hello.txt");
        // 是否存在
        if (file.exists()) {
 
            // 文件
            System.out.println("当前文件是否为文件" + file.isFile());
            // 路径(文件夹)
            System.out.println("当前文件的路径" + file.isDirectory());
        } else {
            System.out.println("文件不存在");
            try {
                file.createNewFile();
                System.out.println("文件已经被成功创建");
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("文件无法被创建");
            }
        }
    }
}
public class FolderDemo01 {
 
    public static void main(String[] args) {
        // File folder = new File("my new folder/one/two/three/main");
        // if (folder.mkdirs()) {
        // System.out.println("文件夹创建成功");
        // } else {
        // if (folder.exists()) {
        // System.out.println("文件已经存在不能再创建");
        // } else {
        // System.out.println("文件夹创建失败");
        // }
        // }
        //
        // 修改文件夹的名称,移动文件夹
        File folder = new File("my new folder-new/one/2");
        File newfolder = new File("my new folder-new/2");
        if (folder.renameTo(newfolder)) {
            System.out.println("done");
        } else {
            System.out.println("file");
        }
    }
}
文件属性的读取
 
 
 
public class ReadFileDemo01 {
 
    public static void main(String[] args) {
        File file = new File("test.txt");
        // 判断文件是否存在
        System.out.println("判断文件是否存在:" + file.exists());
        // 读取文件名称
        System.out.println("读取文件名称:" + file.getName());
        // 读取文件路径
        System.out.println("读取文件路径:" + file.getPath());
        // 读取文件绝对路径
        System.out.println("读取文件绝对路径:" + file.getAbsolutePath());
        // 获取文件的父级路径
        System.out.println("获取文件的父级路径:" + new File(file.getAbsolutePath()).getParent());
        // 读取文件大小
        System.out.println("读取文件大小:" + (float) file.length() / 1000 + "kb");
        // 判断文件是否被隐藏
        System.out.println("判断文件是否被隐藏:" + file.isHidden());
        // 判断文件是否可读
        System.out.println("判断文件是否可读:" + file.canRead());
        // 判断文件是否可写
        System.out.println("判断文件是否可写:" + file.canWrite());
        // 判断文件是否为文件夹
        System.out.println("判断文件是否为文件夹:" + file.isDirectory());
 
    }
 
}
 
文件属性的设置
 
            file.setReadable(false);
            // 将文件设定为可读
            file.setWritable(true);
            // 将文件设定为只读
            file.setReadOnly();
遍历文件夹
 
public class FileDemo03 {
 
    public static void main(String[] args) {
        // printFiles(new File("/Users/macinosh/eclipse-workspace"));
        printFiles(new File("../test"), 1);
    }
 
    private static void printFiles(File dir, int tab) {
        // 如果是一个文件夹的前提,把文件遍历出来
        if (dir.isDirectory()) {
            File next[] = dir.listFiles();
            for (int i = 0; i < next.length; i++) {
                for (int j = 0; j < tab; j++) {
                    System.out.print("|--");
                }
                System.out.println(next[i].getName());
                if (next[i].isDirectory()) {
                    printFiles(next[i], tab + 1);
                }
            }
        }
    }
 
}
 
文件的简单读写
 
public class FileDemo04 {
 
    public static void main(String[] args) {
        File file = new File("text.txt");
        if (file.exists()) {
            System.err.println("exist");
            try {
                // 用于文件输入3个流
                FileInputStream fis = new FileInputStream(file); // 创建文件输入流,字节流
                InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); // 创建文件输入流的reader,
             //字符流,当字节流转换为字符流的时候,就需要指定文本的编码
                BufferedReader br = new BufferedReader(isr); // 创建带有缓冲区的输入流reader
 
                String Line;
                while ((Line = br.readLine()) != null) { // 读取内容
                    System.out.println(Line);
                }
                // 关闭文件的输入流,先打开的后关闭,后打开的先关闭
                br.close();
                isr.close();
                fis.close();
 
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        // 文件的输出流
        try {
            File newfile = new File("newtext.txt");
            FileOutputStream fos = new FileOutputStream(newfile);
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
            BufferedWriter bw = new BufferedWriter(osw);
 
            bw.write("作者:汉乐府 ");
            bw.write("青青园中葵,朝露待日晞。 ");
            bw.write("阳春布德泽,万物生光辉。 ");
            bw.write("常恐秋节至,焜黄华叶衰。 ");
            bw.write("百川东到海,何时复西归? ");
            bw.write("少壮不努力,老大徒伤悲。 ");
 
            bw.close();
            osw.close();
            fos.close();
 
            System.out.println("写入完成");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
    }
 
}
Java IO 简介
 
IO也可以写作为 "i/O" ,也可以理解为In和Out,即输入与输出。所以,IO体系的基本功能就是: 读和写。
IO流作用:读写设备上的东西,硬盘文件、内存、键盘、网络...
根据数据的走向,可分为:输入流,输出流。
 
根据处理的数据类型,可分为:字节流、字符流。
 
字节流和字符流的区别
 
字节流可以处理所有类型的数据,如MP3、图片、文字、视频等。在读取时。读到一个字节就返回一个字节。
在Java 中对应的类都以“Stream”结尾。
字符流仅能够处理纯文本数据,如txt文本等。在读取时,读到一个或者多个字节,先查找指定的编码表,然后将查到的字符返回。
在Java中对应的类都以”Reader“ 或 "Writer" 结尾。
多线程
进程:正在执行中的程序,其实就是应用程序在内存中运行的空间。
 
线程:进程中的一个执行单元,负责进程中的程序的允许,一个进程中至少要有一个线程。
 
一个进程中可以是有多个线程的,这个应用程序也可以称之为多线程程序。
 
可以实现多部分程序同时执行,专业术语称之为 并发
 
多线程的使用可以合理使用CPU的资源,如果线程过多会导致降低性能。
 
CPU处理程序时,是通过快速切换完成的,在我们看来好像随机一样。
 
创建线程的两种方式:
 
继承Thread类
1. 定义一个类继承Thread
2. 重写run方法
3. 创建子类对象,就是创建线程对象
4. 调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法
 
问题及回答
 
线程调用run方法和调用start方法区别:
 
调用run方法不开启线程,仅是对象调用方法。
调用start开启线程,并让jvm调用run方法在开启的线程中执行。
为什么继承Thread类?
 
继承thread类,因为thread类描述线程事物,具备线程应该有的功能。
为什么不只讲创建thread类的对象呢?
 
Thread thread = new Thread();
 
thread.start();
 
创建线程的目的是什么?
 
为了建立单独的执行路径,让多部分代码实现同时执行,也就是线程创建并执行需要给定的代码。(线程的任务)。
主线程的定义
 
主线程,该任务定义在main函数中,自定义线程需要执行的任务都定义在run方法中。
 
thread类中run方法内部的任务并不是我们所需要,只要重写run方法,既然Thread类已经定义了线程任务的位置,只要在位置中定义任务即可。所以进行了重写run方法动作。