Java学习笔记
1、封装(高内聚、低耦合)
-
封装要将属性进行私有化
-
private name
-
private age
-
-
封装后,不能再用对象名.属性名进行调用,而是需要进行get/set方法对属性进行设置和获取
package com.mao.day04; public class Student { //私有化成员变量 private String name; private int age; private String sex; //Alt + insert 快捷键入get/set方法 //get方法需要返回对应的类型 //set方法则不需要返回返回值,但是需要形式参数;用于接收主函数中传入的参数值 //this.name就是把这个单独的Student类的属性给赋值,进而让get方法调用后返回主函数输出 //构造一个有参的方法,这里的属性,是直接对应方法传过来的参数值的,而不是通过get/set方法 public void Speak(String name, int age, String sex) { System.out.println("我叫" + name + "\t今年" + age + "岁\t" + "性别" + sex); System.out.println("======================================================获取后"); } //空参,但获取了此类中已经有的属性值 public void Speak() { System.out.println("我叫" + this.name + "\t今年" + this.age + "岁\t" + "性别" + this.sex); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { //在set方法中可以做限定,以保证系统的安全,例如 if (age > 120 || age < 0) { //意味着不合法年龄 this.age = -1; System.out.println(this.name+"的年龄不合法"); } else { this.age = age; } } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } public class Main { public static void main(String[] args) { Student student = new Student(); student.setName("毛锋程"); student.setAge(124); student.setSex("男"); //可以直接用get方法来获取属性值,前面已经利用set方法进行赋值 System.out.println("名字是:" + student.getName()); //直接参数传递,不通过get/set方法 student.Speak("陈德蔓", 24, "女"); //通过get/set方法获取属性值 student.Speak(); } }
1.1 封装的作用
-
提高程序的安全性、保护数据
-
隐藏代码的实现细节
-
统一接口
-
系统可维护性增加
2、继承
1. (Ctrl + H可以查看层次结构,发现Object是最头部的父类,所有类都继承Object类)
1.1 子类可以得到父类的所有方法以及共有属性(即使子类中什么都没有写)
package com.mao.day04; public class Teacher extends Person { public static void main(String[] args) { Teacher teacher = new Teacher(); //继承了父类的方法 teacher.say(); //继承了父类没有限制的属性值 System.out.println("我继承了父类的" + teacher.money + "元"); } } package com.mao.day04; public class Person { //默认的default权限(可被继承,不受限制),而private则不可被继承,以及protected int money = 1_0000_0000; //可以被继承的方法 public void say() { System.out.println("我继承了父类!"); } } ================================================================================================================================ //若父类的属性是私有属性,如下,那么则需要用get/set方法进行获取继承 public class Teacher extends Person { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.say(); //使用get方法进行获取父类的属性值 System.out.println("我继承了父类的" + teacher.getMoney() + "元"); } } package com.mao.day04; public class Person { private int money = 1_0000_0000; public void say() { System.out.println("我继承了父类!"); } //使用get/set方法让父类的私有属性可以被继承访问,因为一般父类的方法可以被继承但是属性一般都是私有化的 public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } }
-
空参构造优先调用父类的,super( ) 而后调用子类的this( )
-
结论:
-
父类必须包含空参构造,否则子类的无参构造和有参构造皆不能被实现
-
//测试类,调用子类的方法 public class Main { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.test("小毛"); teacher.test1(); } } //父类,部署一些方法以及属性值,让子类对其访问调用 public class Person { protected String name = "毛锋程"; //无参构造 public Person() { System.out.println("父类的无参构造优先被调用!"); } //有参构造(对应子类中的super("毛锋程")子类中的无参构造可以直接调用父类中的有参构造) public Person(String name) { System.out.println("名字是:" + this.name); } public void Speak() { System.out.println("我是父类的方法"); } } //子类继承父类的所有方法,以及非私有属性值 public class Teacher extends Person { private String name = "mfc"; //子类的无参构造 public Teacher() { //属于一个隐藏代码,默认是有一个super()方法的,调用父类的无参构造 //调用构造器都必须放在无参构造的第一行去执行,无论是super()还是this() super("毛锋程"); System.out.println("子类的无参构造后被调用!"); } //子类的有参构造 public Teacher(String name) { this.name = name; } //调用父类的方法 public void test1() { System.out.println("================================="); Speak(); this.Speak(); super.Speak(); } public void Speak() { System.out.println("我是子类的方法"); } //super可以用于调用父类的方法和属性值(除开private私有类) public void test(String name) { //传过来的形式参数 System.out.println("传递的名字是:" + name); //this这个类的属性值 System.out.println("子类的名字是:" + this.name); //继承父类的属性值 System.out.println("父类的名字是:" + super.name); } }
2. Super注意点
3. 方法的重写(子类的个性化,只和左边的数据类型有关)
3.1 父类的引用指向子类、子类重写父类就调重写的方法、否则还是父类的方法、父、子类方法同存,执行子类、Father f1 = new Son( );
-
static 方法,属于类,它不属于实例
-
final 常量
-
private 方法
以上三部分不可进行重写
//继承 public class B extends A { //重写方法 @Override public void say() { System.out.println("B的个性化方法"); } /* public void say() { super.say();//子类重写父类的方法 }*/ } //测试类 public class Main { public static void main(String[] args) { //如果不进行方法的重写,那么只会调用子类,所以需要重写父类方法 //方法的调用只和左边,定义的数据类型有关,B是子类 B b = new B(); b.say(); System.out.println("=============================="); //父类的引用指向B,所以输出的也是B的方法 A a = new B(); a.say(); System.out.println("=============================="); //父类单独实现方法 A a1 = new A(); a1.say(); } } //重写都是方法的重写,和属性无关 public class A { public void say() { System.out.println("A的方法"); } }
3.2 关键点
3、多态(方法的多态,属性无多态性)
4、instance of(判断对象的类型)
-
父类转子类,需要强制转换,但可能会丢失方法
-
子类转父类,可以直接转,因为子类可以使用父类的方法
-
5、static关键字(随类加载时就存在)
-
static静态代码块,只执行一次!就是在类加载的时候
-
非静态方法可以去调用静态方法(因为静态方法开始就存在,可以被调用)
-
静态方法不能去调用普通方法(还没有存在)
5.1 静态导入包
import static java.lang.Math.random; import static java.lang.Math.PI;
//若不导入包,而只是导入工具类,那么在用的时候还是需要 Math.random()才可以使用 //可以直接导入方法包 import static java.lang.Math.random; import static java.lang.Math.PI; public class Test{ public static void main(String[] args){ System.out.println(random()); System.out.println(PI); } }
6、Final是”断子绝孙“ 常量修饰符
7、抽象类
-
abstract,抽象方法,只有方法名字,没有方法的实现!
-
抽象类的所有方法,继承了它的子类,都必须要实现其它的方法,除非它本身也是抽象类,那么就需要它的子子类去实现
-
类需要去继承,所以必须要继承,而extends只有单继承的属性,所以引入接口,接口可以多继承
7.1 特点
-
抽象类不能new,只能靠子类去实现它:约束!
-
抽象类中可以写普通方法
-
抽象方法必须在抽象类中
-
抽象类存在构造器,用于子类去调用,super( )方法
-
存在的意义是提高开发效率
8、接口(只有规范,专业约束)
8.1 interface 定义的关键字,接口都需要有实现类
-
接口中所有定义其实都是抽象的 方法的public abstract 默认状态
-
常量的public static final状态
//在接口中,只需要定义方法,而不需要具体实现,在类中需要实现就必须重写方法 public interface UserService { void add(String name); void delete(String name); void update(String name); void query(String name); } package com.mao.day04; //类可以实现接口 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() { } } public interface TimeService { void timer(); }
9、异常机制(Ctrl + Windows + Alt + T)
package com.mao.day04.exception; public class Test { public static void main(String[] args) { try { new Test().test(10,0); } catch (ArithmeticException e) { throw new RuntimeException(e); } finally { System.out.println(System.out); } } //假设这个方法中处理不了这个异常,在方法上抛出这个异常,也可直接在方法体中抛出异常 public void test(int a, int b) throws ArithmeticException { if (b == 0) { throw new ArithmeticException();//主动的抛出异常,一般用于方法中 } } } /* * int a = 10; int b = 0; //try则是一个监控区域,用于监控代码块中是否会出现问题 try{ System.out.println(a/b); } //catch主要是捕获异常的类型 //同时有多个异常时,从小到大进行书写,否则报错 catch (Error er){ System.out.println("ERROR"); } catch (Exception e){ //打印栈的错误信息 e.printStackTrace(); System.out.println("b作为分母不能为0"); } catch (Throwable t){ System.out.println("Throwable"); } finally { //finally一般用于释放内存或结束程序的操作 //主要处理善后工作,假设IO流的关闭、资源的关闭 System.out.println("程序结束"); } * */