面向对象编程
初识面向对象
Object-Oriented Programming
本质:以类的方式组织代码,以对象的组织(封装)数据
方法回顾和加深
方法定义
修饰符 返回类型 方法名(参数列表){ 方法体; //return ... }
break---跳出switch,结束循环
return---方法结束,返回一个结果
方法调用
-
静态方法 static
和类一起加载的
直接通过 类名.方法() 调用
-
非静态方法
类实例化之后才存在
需要实例化类,对象类型 对象名 = 对象值
Student student=new Student();
student.say();//调用
-
形参,实参
-
值传递,引用传递
值传递 public class Demo1 { public static void main(String[] args) { int a = 1; System.out.println(a);//1 Demo1.change(a); System.out.println(a);//1 } public static void change(int a){ a = 10; } } 引用传递 public class Demo1 { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name);//null Demo1.change(person); System.out.println(person.name);//cc } public static void change(Person person){ person.name = "cc"; } } class Person{ String name; }
-
this关键字
对象的创建和分析
-
类是一种抽象的数据类型,类(属性,方法)
-
对象是抽象概念的具体事例
-
一个项目只存在一个main方法
-
构造
-
在创建对象时必须要调用的
-
必须与类名字相同
-
必须没有返回类型,也不能写void
-
可以实例化对象,赋初始值this.name="cc"
-
有参构造,一旦定义了有参构造,无参构造必须显示定义
public Person(){} public Person(String name){ this.name = name; }
alt+insert生成构造函数
-
-
创建对象内存分析
面向对象三大特性
封装
数据的隐藏---属性私有,get/set
public class Demo1 { public static void main(String[] args) { Student s1 = new Student(); //s1.name = "cc"; 错误,属性私有 s1.setName("cc"); System.out.println(s1.getName()); s1.setAge(-1);//不合法 System.out.println(s1.getAge()); } } public class Student { private String name; private int id; private char sex; private int age; public String getName(){ return this.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; } }
alt+insert---自动生成get,set
-
提高程序安全性,保护数据
-
隐藏代码的实际细节
-
统一接口
-
系统可维护性增加
继承
-
继承的本质是对一批类的抽象
-
extends,子类是父类的扩展
public class Student extends Person{}
-
Java中只有单继承,没有多继承
-
子类继承父类,就会拥有父类的全部方法(public)
-
父类private修饰的变量可以用方法调用
object
//ctrl+H ---object
在Java中所有类都默认直接,间接继承object类
super
调用父类构造器super,this必须在子类的第一行
super必须只能出现在子类的方法或构造方法中
super和this不能同时调用构造方法
public class Demo1 { public static void main(String[] args) { Student student = new Student(); student.test("柒"); student.test1(); } } //父类 public class Person { protected String name = "cc"; public Person() { System.out.println("Person无参执行"); } public void print(){//private不能被继承 System.out.println("Person"); } } //子类 public class Student extends Person{ public Student() { //隐藏代码:调用了父类无参构造 //调用父类的构造器必须在子类的第一行,this也是 super();//默认调用 System.out.println("Student无参执行"); } private String name = "qq"; public void test(String name){ System.out.println(name);//柒 System.out.println(this.name);//qq System.out.println(super.name);//cc } public void print(){ System.out.println("Student"); } public void test1(){ print(); this.print(); super.print(); } }
super vs this
-
代表对象不同:
-
this本身调用这个对象
-
super代表父类对象的应用
-
-
前提:
-
this没有继承也可以使用
-
super只能在继承条件下使用
-
-
构造方法:
-
this()本类的构造
-
super()父类的构造
-
重写
public才可以
需要有继承关系,子类重写父类的方法:
-
方法名必须相同
-
参数列表必须相同
-
修饰符范围可以扩大不能缩小
public class Demo1 { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.test(); //父类的引用指向子类 Person person = new Teacher(); person.test(); } } public class Person { /* public static void test(){ System.out.println("Person=>test()"); } */ public void test(){ System.out.println("Person=>test()"); } } public class Teacher extends Person{ /* public static void test(){ System.out.println("Teacher=>test()"); } */ public void test(){ System.out.println("Teacher=>test()"); } }
静态方法和非静态方法区别很大:
-
非静态方法:可选择重写
-
静态方法:方法的调用只和左边定义的数据类型有关
重写的方法和父类必须一致,方法体不同
为什么要重写:
父类的功能,子类不一定需要或者不一定满足
alt+insert: override
多态
public class Demo1 { public static void main(String[] args) { //一个对象的实际类型是确定的,可以指向的引用类型就不确定了 Student s1 = new Student(); //Student能调用的方法都是自己的或继承父类的 Person s2 = new Student(); //Person是父类,可以指向子类,但是不能调用子类独有的方法 Object s3 = new Student(); s2.run();//子类重写了父类方法,执行子类 s1.run(); //对象能执行哪些方法主要看对象左边的类型 //s2.eat();报错 ((Student)s2).eat(); s1.eat(); } } public class Person { public void run(){ System.out.println("run"); } } public class Student extends Person{ @Override public void run() { System.out.println("son"); } public void eat(){ System.out.println("eat"); } }
多态是方法的多态
父类和子类有联系才可以,否则类型转换异常ClassCastException
存在条件:继承关系,方法需要重写,父类引用指向子类对象 Father f1 = new Son();
不能重写的:
static方法,属于类,不属于实例
final常量
private私有
instanceof
System.out.println(X instanceof Y);
X,Y是否存在父子关系,编译是否报错
public class Demo1 { public static void main(String[] args) { Object object = new Student(); System.out.println(object instanceof Student);//T System.out.println(object instanceof Person);//T System.out.println(object instanceof Object);//T //System.out.println(object instanceof Teacher); //F //System.out.println(object instanceof String); //F } }
类型转换
方便方法的调用
public class Demo1 { public static void main(String[] args) { //类型转换:父 子 Person obj = new Student(); //obj将这个对象转换为Student类型,就可以使用Student类型的方法了 ((Student)obj).go(); } } public class Person{} public class Student extends Person{ public void go(){ System.out.println("go"); } }
static关键字
静态变量可以直接使用类名访问(多线程)
非静态方法可以调用静态方法
静态代码块,只执行一次
抽象类和接口
抽象类
abstract修饰,,,规范
抽象类里可以写普通方法,抽象方法必须在抽象类中
public abstract class Teacher{} public abstract void doSomething();
抽象类的所有方法,继承了它的子类,都必须要实现它的方法,除非子类也是抽象类,那么子子类
不能new抽象类,只能靠子类去实现它
接口
接口可以多继承--- interface
只有规范,自己无法写方法
实现了接口的类必须重写接口中的方法
public interface Person{ void add(String name); void delete(String name); } public class person1 implements Person{ //重写方法 }
接口就是定义一些方法,让不同的人实现
接口不能实例化,无构造方法
内部类及OOP实战
-
成员内部类
Inner定义---
要通过外部类实例化内部类,可以获得外部类的私有属性私有方法
Outer.new Inner() = outer.new Inner();
Inner.in();
-
静态内部类
-
局部内部类
-
匿名内部类