java面向对象
面向对象 & 面向过程
- 面向过程思想
- 步骤清晰简单,第一步做什么,第二步做什么…
- 面向过程适合处理一些较为简单的问题
- 面向对象思想
- 物理类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考,最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题
- 面向对象编程(Object-Oriented Programming,OOP)的本质就是:以类的方式组织代码,以对象的形式封装数据
- 三大特性
- 封装
- 继承
- 多态
什么是方法
- 方法的定义
- 修饰符
- 返回类型
- return:方法结束的标志
- 方法名:注意规范 见名知意
- 参数列表:{参数类型 参数名
- 异常抛出
- 方法的调用
- 静态方法 与类一起加载 非静态的可以调静态 非静态可以直接调非静态 但是静态不可以直接调非静态
- 非静态方法
- 值传递与引用传递 引用传递传递的是对象 指向的是对象的属性
- 实参与形参
- this关键字
构造器
//必须和类名相同 且没有返回值
String name;
//使用new关键字 本质就是在调用构造器
//用来初始化值
public Person(){};//无参构造
//一旦定义了有参构造 无参构造就必须显式定义
public Person(String name){ //有参构造
this.name = name;
}
创建对象时的堆栈关系
封装(数据的隐藏)
//高内聚 低耦合
//属性私有, get/set 方法public
/*
作用:
1、提高程序的安全性 保护数据
2、隐藏代码的实现细节
3、统一接口
4、增加系统的可维护性
*/
package com.zhhl.oop;
/**
* @ClassName User
* @Description TODO
* @Author handsome boy
* @Date 2020/11/23
*/
public class User {
private int id;
private String name;
private int age;
public User(){}; //无参构造
public User(int id, String name,int age) { //有参构造
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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>120 || age <0){
this.age = 3;
}else{
this.age = age;
}
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) {
User user = new User();
user.setName("I am handsome!!"); //通过set方法来设设置属性值
System.out.println(user.getName()); //通过get方法来获取属性值
user.setAge(18);
System.out.println(user.getAge());
}
继承
//子类继承父类 就会拥有父类中的所有方法
//extends的意思是“扩展” 子类是父类的扩展
//java类中只有单继承 没有多继承
//继承关系的两个类 一个为子类(派生类) 一个为父类(基类)
//存在 is a 的关系
public class Person {
//子类继承父类 可直接调用父类的属性 如果属性为private则不会调用
public String name = "老王";
public void test(){
System.out.println("我是父类 Person");
}
//student类继承person类
public class Student extends Person {
}
public static void main(String[] args) {
Student student = new Student();
student.test();
System.out.println(student.name);
}
//打印结果
我是父类 Person
老王
super的作用
super注意点:
1、super调用父类的构造方法 必须在构造方法的第一个
2、super 必须只能出现在子类的方法或者构造方法中
3、super 和 this 不能同时调用构造方法
VS this:
1、代表的对象不同
this: 本身调用者这个对象
super: 代表父类对象的应用
2、前提
this:没有继承也可以使用
super:只能在继承条件下使用
3、构造方法
this(); 本类的构造
super(); 父类的构造
被final定义的类无法被继承
//父类
public class Person {
protected String name = "老王Per";
public Person(){ //如果父类只定义了有参构造器 那么子类也只能调用父类的有参
System.out.println("父类无参构造执行了");
}
//如果该方法为私有 则无法调用 只能通过构造去实现
public void test(){
System.out.println("我是父类 Person");
}
}
//子类
public class Student extends Person {
private String name = "老王Stu";
public Student(){
//隐藏代码 只能在第一行
super();
System.out.println("子类无参构造执行了");
}
public void print(){
System.out.println("我是子类 Student");
}
public void test2(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
public void test(){
print();
this.print();
super.test();
}
}
//启动类
public static void main(String[] args) {
Student student = new Student();
student.test2("形参老王");
student.test();
}
//打印结果
父类无参构造执行了
子类无参构造执行了
形参老王
老王Stu
老王Per
我是子类 Student
我是子类 Student
我是父类 Person
重写
- 需要有继承关系 子类重写父类的方法
1、方法名必须相同
2、参数列表必须相同
3、修饰符可以扩大 但是不能缩小 public > protected >default >private
重写:子类的方法必须和父类一致 方法体不同。
为什么要重写: 父类的功能 子类不一定需要 或者不一定满足
//父类
public class B {
public void test(){
System.out.println("BBBBB");
}
}
//子类
public class A extends B {
@Override
public void test() {
System.out.println("AAAAA");
}
}
//启动类
public class Demo {
public static void main(String[] args) {
A a = new A();
a.test();
//父类的引用指向子类
B b = new A();
b.test();
}
}
//打印结果
AAAAA
AAAAA
多态
- 多态存在的条件
- 有继承关系
- 子类重写父类方法
- 父类引用指向子类对象 father f1 = new son();
多态是方法的多态,属性没有多态
- 不能被重写的
- static 方法 属于类不属于实例
- final 常量
- private 修饰的方法
//父类
public class Person {
public void run(){
System.out.println("far");
}
}
//子类
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
//测试类
public class demo {
public static void main(String[] args) {
Student s1 = new Student();
//父类的引用指向子类
Person s2 = new Student();
Object s3 = new Student();
s2.run(); //子类没重写 父类可以执行自己的 子类一旦重写 就会去执行子类的
s1.run(); //子类重写父类的方法 会执行子类的方法
((Student) s2).eat();// 如果是子类独有的方法 父类的引用要做强制类型转换
}
}
//打印结果
son
son
eat
static
private String name ="7788"; //非静态变量
private static int age = 12; //静态变量
public static void main(String[] args) {
Teacher teacher = new Teacher();
System.out.println(teacher.name);
System.out.println(teacher.age);
System.out.println(Teacher.age);
}
//静态代码块
public class Test {
{
System.out.println("匿名代码块");
}
static {
System.out.println("static代码块"); //只执行一次 下次调用只打印 匿名代码块 构造器
}
public User(){
System.out.println("构造器");
}
}
//打印
static代码块
匿名代码块
构造器
抽象类(abstract)与 接口(interface)
抽象类:
- 因为抽象类实在类上加上abstract关键字 ,逃脱不了class 因此只能被单继承
- 不可以被实例化
- 有抽象方法的一定是抽象类 抽象类中可以写普通方法
接口:
- 声明接口的关键字是interfaces
- 接口可以多实现 通过implements关键字
- 方法前 默认隐藏 public abstract
- 接口中可以定义常量 默认隐藏 public static final
- 不能被实例化 没有构造器
内部类
public class Outer {
private int id= 7788;
public void outer(){
System.out.println("外部");
}
//内部类
class Inner{
public void inner(){
System.out.println("内部");
}
//获得外部类的私有属性 如果为静态内部类 则获取不到非静态的私有属性
public void getId(){
System.out.println(id);
}
}
//测试类
public class Demo {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.inner();
inner.getId();
}
}
//匿名内部类
public class Outer {
private int id= 7788;
public static void main(String[] args) {
//没有名字初始化类 不用将实例保存到变量中
new Outer2().ou();
}
}
class Outer2{
public void ou(){
System.out.println("111");
}
}
自定义异常
public class MyException extends Exception { //继承了Expection 该类就为一个异常类
public int deatil;
public MyException(int deatil) {
this.deatil = deatil;
}
//异常信息打印
@Override
public String toString() {
return "MyException{" + "deatil=" + deatil + '}';
}
}
//测试
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(11);
} catch (MyException e) {
System.out.println("MyException"+e);
}
}
}