Java面向对象
Java面向对象
面向对象(Object-Oriented Programming)编程本质:
以类的方式组织代码,以对象的方式封装数据
三大特性
封装
继承
多态
01、类与对象的创建
package com.oop.Demo01;
/**
* Created by Q on 2022/1/15.
*/
public class Demo01 {
public static void main(String[] args) {
// Student.say(); 静态方法可直接调用
// 非静态方法要先实例化
Student student = new Student();
student.say();
}
//静态方法和类一起加载
public static void a(){
// b();
}
//非静态方法是在类实例化后才存在的,故不能有静态方法调用
public void b(){
}
}
值传递
package com.oop.Demo01;
/**
* Created by Q on 2022/1/16.
*/
public class Demo02 {
public static void main(String[] args) {
//值传递
int a = 10;
System.out.println(a); //10
Demo02 demo02 = new Demo02();
demo02.change(a);
System.out.println(a); //10
}
public static void change(int a){
a = 1;
}
}
02、构造器
又叫构造方法
package com.oop.Demo02;
/**
* Created by Q on 2022/1/18.
*/
public class Person {
//一个类即使什么都不写,也存在一个方法 public Person() {} java--->class文件
//显示的定义构造器
String name; //null
int age;
//作用:实例化初始值
//使用new关键字必须有构造器,因为本质是在调用构造器
public Person() {
}
//有参构造
//使用有参构造,必须显式定义无参构造否则报错
// Person(String)in Person cannot be applied to()
//快捷键 alt+insert
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
public static void main(String[] args) {
Person person = new Person("Q",10);
System.out.println(person.name);
System.out.println(person.age);
}
*/
}
构造器:
-
和类名相同
-
没有返回值
-
作用:
1、实例化初始值
2、使用new关键字本质是在调用构造器
-
注意点:
1、使用有参构造,必须显式定义无参构造,否则报错
2、快捷键 alt+insert
扩展 创建对象内存分析
待完善
待完善
03、封装
将类中属性(+少方法)私有化
package com.oop.Demo03;
/**
* Created by Q on 2022/1/20.
*/
public class Student {
//封装
//属性私有
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0 && age < 120){
this.age = age;
}else {
this.age = -1;
}
}
}
04、继承
对象抽象出类 对象抽象----->类
子类抽象出父类 子类抽象------>父类 子类继承父类
4-1 Object类
4-2 super this
package com.oop.Demo04;
/**
* Created by Q on 2022/1/20.
*/
//父类
//java中,所有类直接或者间接继承Object类
public class Person {
//私有属性不可继承
private int money = 1_0000_0000;
protected String name = "Person_Q";
public Person() {
System.out.println("父类无参构造");
}
public void print(){
System.out.println("Person");
}
public void say(){
System.out.println("说话了");
}
//get set
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
package com.oop.Demo04;
/**
* Created by Q on 2022/1/20.
*/
//子类(继承类) ctrl+H:查看类继承结构
//继承父类所有方法
public class Student extends Person {
private String name = "Student_Q";
public Student() {
//隐藏代码:默认调用父类无参构造
super(); //只能放在子类构造器第一行
System.out.println("子类无参构造");
}
public void print(){
System.out.println("Student");
}
public void test1(){
print(); //Student
this.print(); //Student
super.print(); //Person
}
public void test(String name){
System.out.println(name); //test_Q
System.out.println(this.name); //Student_Q
System.out.println(super.name); //Person_Q
}
}
/**
public static void main(String[] args) {
com.oop.Demo04.Student s1 = new com.oop.Demo04.Student();
s1.say();
s1.test("test_Q");
}
*/
super注意点:
1、super调用父类构造方法,必须是在构造器方法的第一个
2、super只能出现在子类或者构造方法中
3、super和this不能同时调用构造方法!
VS this
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的引用
前提不同:
this:没有继承也可以使用
super:只能在继承的条件下才可以使用
构造方法:
this:本类的构造
super:父类的构造
4-3 方法重写
重写是方法的重写和属性无关
//不是重写
public class A {
public static void test(){
System.out.println("A==>test");
}
}
public class B extends A{
public static void test() {
System.out.println("B==>test");
}
}
public class Application {
public static void main(String[] args) {
//父类的引用指向子类
A a = new B();
a.test(); //A==>test
B b = new B();
b.test(); //B==>test
}
}
//重写
public class A {
public void test(){
System.out.println("A==>test");
}
}
public class B extends A{
//注解
@Override //重写
public void test() {
System.out.println("B==>test");
}
}
public class Application {
public static void main(String[] args) {
A a = new B();
B b = new B();
a.test(); //B==>test
b.test(); //B==>test
}
}
重写小结:要是非静态方法
-
需要有继承关系,子类重写父类的方法!
-
方法名必须相同,参数列表必须相同
-
修饰符:
范围可以扩大:public > Protected > Default > private
-
抛出的异常:
范围可以被缩小,但不能扩大;
ClassNotFountException —> Exception(大)
-
重写,子类的方法和父类必须要一致,方法体不同!
为什么需要重写?
父类的功能,子类不一定需要,或者不一定满足!
05、多态
多态存在的必要条件:
- 继承
- 重写 (子类重写父类方法,方法名必须相同)
- 父类引用指向子类对象:Parent p = new Child();
06、instanceof关键字
X instanceof Y X是否是Y的实例
package com.oop;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
import com.oop.demo06.Teacher;
public class Application {
public static void main(String[] args) {
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object = new Student();
//System.out.println(X instanceof Y);//能不能编译通过,就取决于X和Y之间是否存在父子关系;
//结果是true或者false ,X所指向的实例类型是Y的子类型,或者 X和 Y是有关系的
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Object);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof String);//false,String是 Object lang包下面的,更没关系了
System.out.println("===================================");
Person person = new Student();
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Object);//true
System.out.println(person instanceof Teacher);//false
//System.out.println(person instanceof String);//编译报错!string和 person同级,它是两条线
System.out.println("===================================");
Student student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
//System.out.println(student instanceof Teacher);//false,编译报错!
// instanceof是一个比较转换的过程,比较肯定是两边有关系的才会返回true或者false
//System.out.println(student instanceof String);//false,编译报错! 两者没关系会直接报错
}
}
多态总结:
1. 父类引用指向子类的对象(子类引用指向父类的对象肯定是不行的)
2. 把子类转换为父类,也就是向上转型:不用强制转换;
3. 把子类转换为父类,也就是向下转型:需要强制转换;(可能会丢失一些方法)
4. 方便方法的调用,减少重复的代码!简洁
07 、static关键字小结
静态属性
//static
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(Student.score);这是不行的
System.out.println(s1.age);
System.out.println(s1.score);
}
}
静态方法
//static
public class Student {
private static int age;//静态的变量 多线程!
private double score;//非静态的变量
public void run(){//非静态方法可以调用静态方法里的所有东西
go();
}
public static void go(){//静态方法可以调用静态方法里的所有东西
}
public static void main(String[] args) {
new Student().run();//对象.方法
Student.go();
go();
}
}
静态代码块
public class Person {
//2:赋初值~
{
//代码块(匿名代码块)
//没有名字,程序不会主动调用这些模块
//匿名代码块:创建对象时就自动创建了,而且在构造器之前
System.out.println("匿名代码块");
}
//1 : 只执行一次~
static {
//静态代码块
//可以在里面加载一些初始化的数据
//静态代码块:类一加载就直接执行,永久只执行一次
System.out.println("静态代码块");
}
//3
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("=================");
Person person2 = new Person();
}
/*
结果:
静态代码块
匿名代码块
构造方法
=================
匿名代码块
构造方法
*/
}
package的一些新特性
//静态导入包~
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);
}
/*
final 通过final修饰的类不能被继承,就没有子类
*/
}
08、抽象类(abstract)
-
抽象类特点
- 抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中
- 抽象类不可以直接创建对象,原因:调用抽象方法没有意义
- 只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象,否则该子类还是一个抽象类
-
abstract不能和哪些关键字共存?
- private 被私有的成员只能在本类中调用,而abstract强制重写抽象方法,二者冲突
- final final表示最终的,被修饰的类和方法不能被继承和重写,与abstract强制重写抽象方法冲突
- static 无意义
//abstract修饰的类为抽象类,java的类是单继承(接口可以多继承)
public abstract class Action {
//抽象方法,可以实现约束作用,让继承的子类来实现方法。
//abstract,抽象方法,只有方法名字,没有方法的实现!
public abstract void doSomething();
//抽象类不能new出对象,只能用子类去实现。
//抽象类里可以写普通方法
//抽象方法必须在抽象类中
//抽象的抽象:约束
//存在的意义,提高开发效率。
}
public class A extends Action{
@Override
public void doSomething() {
}
}
09、接口
-
接口的成员特点
- 成员变量:只能是常量,并且是静态的,默认有public static final修饰
- 成员方法:只能是抽象方法,默认有public abstract修饰
- 构造方法:接口没有构造方法
package com.oop.Demo06; /** * Created by Q on 2022/1/23. */ //接口 public interface UserService { void add(String name); void delete(String name); void update(String name); void query(String name); } //接口实现类 public class UserServiceImpl implements UserService { @Override public void add(String name) { } @Override public void delete(String name) { } @Override public void update(String name) { } @Override public void query(String name) { } }
10、内部类
- 成员内部类
- 静态内部类(static 修饰)
- 局部内部类
- 匿名内部类
package com.oop.Demo07;
/**
* Created by Q on 2022/1/23.
*/
public class Outer {
private String name;
public void out(){
System.out.println("外部类");
}
public class Inner{
public void in(){
System.out.println("内部类");
}
//作用:获得内部类的私有属性
public void getName(){
System.out.println(name);
}
}
}
/*
public static void main(String[] args) {
Outer outer = new Outer();
outer.out(); //外部类
Outer.Inner in = outer.new Inner();
in.in(); //内部类
in.getName(); //Q
}
*/
小疑惑 UserService userservice = new UserService()
//一个Java类中可以有多个class类,但是只能有一个public class
public class Outer {
public static void main(String[] args) {
new Apple().eat();
//匿名内部类
UserService userservice = new UserService(){
@Override
public void Hello() {
}
};
}
}
//局部内部类
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void Hello();
}
11、类、接口、抽象类小结
类与类,类与接口,接口与接口的关系
- 类与类:继承关系,只能单继承,可以多层继承
- 类与接口:实现关系,可以单实现,也可以多实现。并且可以在继承一个类的同时实现多个接口
- 接口与接口:继承关系,可以单继承,也可以多继承
抽象类和接口的区别
-
成员区别
抽象类:
成员变量:可以是变量,也可以是常量
成员方法:可以是抽象类,也可以非抽象类
构造方法:有
接口:
成员变量:只能是常量
成员方法:只能是抽象类
构造方法:无
-
关系区别
抽象方法:
类与类:继承,单继承
类与接口:实现,单实现,多实现
接口与接口:继承,单继承,多继承 -
设计理念区别
抽象类:体现的是“is a ”的关系,抽象类中定义的是该继承体系的共性功能
接口:体现的是“like a ”的关系,接口中定义的是该继承体系的个性功能(扩展功能)
12、异常
Error和Exception
Exception
12-1 异常层次结构图示
(引用菜鸟教程)

12-2 关键字
- try
- catch
- finally
- throw
- throws
package com.exception;
/**
* Created by Q on 2022/1/23.
*/
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
//Ctrl+Alt+t 快捷键:捕获结构代码
try{//监控区
System.out.println(a/b); //Exception in thread "main" java.lang.ArithmeticException: / by zero
}catch (ArithmeticException e){ //捕获
System.out.println(e);
}catch (Error error){
System.out.println("Error");
}catch (Exception exception){
System.out.println("Exception");
}catch (Throwable throwable){
System.out.println("Throwable");
}finally { //善后处理 finally可以不用,用于处理IO流等关闭资源
System.out.println("其他异常");
}
}
}
/*
输出结果:
java.lang.ArithmeticException: / by zero
其他异常
*/
12-3 自定义异常
package com.exception.Demo02;
/**
* Created by Q on 2022/1/23.
*/
public class MyException extends Exception{
private int detail;
//参数大于10抛异常
public MyException(int detail) {
this.detail = detail;
}
@Override
public String toString() {
return "MyException{" + "detail='" + detail + '\'' + '}';
}
}
//测试
public class Test {
//可能出现异常的方法
static void test(int a) throws MyException{
System.out.println("参数:"+a);
if (a > 10){
throw new MyException(a);
}
System.out.println("OK");
}
public static void main(String[] args) {
try {
test(14);
} catch (MyException e) {
System.out.println(e);
}
}
}
/*
参数:14
MyException{detail='14'}
*/
后记(有感)
从2022年1月1号准备开始学习,至今23号,经过23天(实际最多只需要一周就可以搞定,打脸自己flag)断断续续的学习,课程是B站狂神说Java的JavaSE课程,记录了这么一份笔记,其中有的是借鉴偷懒直接c(但是少数),希望可以用来以后回顾。能感觉出来这是一份速学课程,相对而言少了很多知识点,适合急找工作速成。后续再找点资料补充完善java体系。
补充待续

浙公网安备 33010602011771号