面向对象编程
本质:以类的方式组织代码,以对象的组织(封装)数据
抽象
三大特性:封装 继承 多态
创建对象
使用new关键字创建对象:
使用new关键字创建的时候,除了分配内存空间外,还会对创建好的对象进行默认初始化,以及对类中构造器的使用
Demo demo=new Demo();这样的写法代表有引用,用demo这个名字可以去操作这个对象,但是直接new的话就是匿名对象,没有引用指向它,只能在new的一瞬间做一些事情,后来就会被当成垃圾回收掉
package first.basic;
public class Demo06 {
//类对象 static
static double salary =2500;//随类产生 随类消失
//属性: 变量
//实例变量:从属于对象 ; 如果不自行初始化 类型默认值为0 0.0
// 布尔值:默认为false
//除基本类型外 其他默认为null
String name;
int age;//实例变量只有在 类实例化后可被调用
public void add(){
System.out.println(name);//不可调用局部变量
}
}
package first.basic;
public class HelloWorld {
public static void main(String[] args) {
System.out.println( Demo06.salary);
Demo06 d0 = new Demo06();
d0.age=13;
d0.name="存款";
d0.add();
System.out.println(d0.age);
System.out.println(d0.name);
new Demo06().age=13;
new Demo06().name="存款";
new Demo06().add();
System.out.println(new Demo06().age);
System.out.println(new Demo06().name);
}
}
2500.0
存款
13
存款
null
0
null
//可以看出 不赋值 对类中参数修改无效 直接回收
定义类
package Method;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
//引用传递:对象,本质还是值传递
public class M05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//null
M05.change(person);
System.out.println(person.name);//轻轻
}
public static void change(Person person){
//person是一个对象 指向的-->Person person = new Person();
person.name="轻轻";
}
}
//定义了一个Person类 有一个属性 name
class Person{
String name;
}
使用类
package Oop;
public class Application {
public static void main(String[] args) {
//类;抽象的,实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student的具体实例!
Student student = new Student();
Student xiaohong = new Student();
Student xiaoming= new Student();
xiaoming.name="小明";
xiaoming.age=3;
System.out.println(xiaohong.name);//null
System.out.println(xiaohong.age);//0
System.out.println(xiaoming.age);//3
System.out.println(xiaoming.name);//小明
}
}
构造器
alt+insert 快速生成构造器 选Constructor
要求:
- 和类名相同
- 没有返回值(void也不行)
作用:
- 使用new关键字 本质是调用构造器
- 构造器用来初始化
有参构造; 一旦定义了有参构造 无参必须显式定义(即必须在声明一个无参构造)
this指当前类的
package Oop;
public class Person {
//一个类 什么都不写 也会存在一个方法
String name;
//实例化初始值
//使用new关键字 本质是调用构造器
//构造器用来初始化
public Person(){
}
//有参构造; 一旦定义了有参构造 无参必须显式定义(即必须在声明一个无参构造)
public Person(String name){
this.name=name;
}
//alt+insert 快速生成构造器
}
package Oop;
public class Application {
public static void main(String[] args) {
//实例化一个对象
Person person = new Person("qingqing");
System.out.println(person.name);
}
}
引用类型 基本类型(8)
对象是通过引用操作的
属性:字段Field 成员变量
默认:int :0 0.0 char:U0000; boolean:false 引用类型: null
三大性质
封装
封装的作用:
1.提高程序的安全性,保护数据 2.隐藏代码的实现细节 3.统一接口 4.增强系统的可维护性
将对象数据隐藏 不再可以直接查看 修改
属性私有,get/set
package Demo00;
//类 private:私有
public class Student1 {
//属性私有
//名字 年龄 性别
private String name;
private int age;
private char sex;
private int id;
public String school;
//属性无法直接访问修改
//提供一些public 的方法来获得
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
//alt+insert get set
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>120 || age<0){
this.age=3;
}else{
this.age=age;
}
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package Oop;
import Demo00.Student1;
public class Application {
public static void main(String[] args) {
//实例化一个对象
Student1 stu1 = new Student1();
Student1 stu2 = new Student1();
stu1.getName();
stu1.setName("huahua");
System.out.println(stu1.getName());
stu1.setAge(999);
System.out.println(stu1.getAge());
stu1.setId(1220045325);
System.out.println(stu1.getId());
stu2.school="NJUPT";
stu1.setAge(99);
System.out.println(stu2.getName());
System.out.println(stu2.getSex());
System.out.println(stu2.getAge());
System.out.println(stu2.getId());
System.out.println(stu2.school);
}
}
快捷键 alt+insert get set
继承
extends 类与类的关系 is a 关系
Java只有单继承 ,没有多继承
父类
package Oop;
//java 中所有类 都默认继承 Object类
//人 父类
public class Person {
public int money=100000000;
public void say(){
System.out.println("你好");
}
}
子类
package Oop;
//学生类 继承 Person 为子类
public class Student extends Person{
//ctrl h 打开继承树
}
调用
package Oop;
import Demo00.Student1;
public class Application {
public static void main(String[] args) {
//实例化一个对象
Student s1 = new Student();
s1.say();
System.out.println(s1.money);
System.out.println(s1.private_money);//报错 ”私房钱“无法继承
s1.smile();//报错 私有方法无法继承
}
}
java 中所有类 都默认继承 Object类
ctrl h 打开继承树
super-this
- super的注意点:
- super调用父类的构造方法,必须放在子类构造构造器的首行;
- super必须出现在子类的方法或构造方法中;
- super和this不能同时调用构造方法、
- this的注意点:
- 代表对象不同
- this: 子类的对象
- super: 父类的对象
- 前提:
- this: 没有继承也可以使用
- super: 只能在继承条件下才能用
- 构造方法:
- this():本类的构造方法
- super(): 父类的构造方法
- 代表对象不同
父类
package Oop;
//java 中所有类 都默认继承 Object类
//人 父类
public class Person {
public Person( String name) {
System.out.println("Person 无参构造");
}
protected String name="father";
public void print(){
System.out.println("this调用:"+this.name);//没有继承也可使用
System.out.println("Person");
}
}
子类
package Oop;
//学生类 继承 Person 为子类
public class Student extends Person{
//ctrl h 打开继承树
public Student() {
super("name");
//this();//报错 this 也要在第一行 冲突 故不能同时调用
System.out.println("Student执行");
}
private String name="me";
public void test(String name){
System.out.println(name);//形参
System.out.println(this.name);//this。name 当前类的属性
System.out.println(super.name);//父类的属性
}
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
}
调用
package Method;
import Oop.Student;
public class Application {
public static void main(String[] args) {
//Person person = new Person();
//System.out.println(person.name);
//实例化一个对象
Oop.Student s1 = new Student();
s1.test("son");
s1.test1();
}
}
Person 无参构造
Student执行
son
me
father
Student
Student
this调用:father
Person
方法重写
前提:需要有继承关系 子类重写父类的方法
要求:-
- 方法名必须相同
- 参数列表必须相同
- 修饰符 范围可以扩大:public>protected>Default>private(测试不成功???)
- 抛出的异常: 范围可以被缩小 但不能扩大
重写,子类的方法和父类必须一致 方法体不同
意义:
1.子类不一定需要或不一定满足(alt+insert +override) 标志
父类
package Demo01;
public class B {
public static void test(){
System.out.println("B-->test()");
}
public void test1(){
System.out.println("B-->test1()");
}
}
子类
package Demo01;
public class A extends B{
public static void test(){
System.out.println("A-->test()");
}
@Override//注解 有功能的注释
public void test1() {
System.out.println("A-->test1()");
}
}
调用
package Method;
import Demo01.A;
import Demo01.B;
import Oop.Student;
public class Application {
public static void main(String[] args) {
//静态方法:方法的调用只和左边的数据类型有关
//非静态方法: 重写(只能为public)
A a = new A();
a.test();//A
//父类的引用指向了子类
B b = new A();//子类重写了父类的方法
b.test();
a.test1();
b.test1();
}
}
A-->test()
B-->test()
A-->test1()
A-->test1()
多态
1.多态是方法的多态 属性没有
2.父类和子类:有联系 类型转换异常 ClassCastException!
3.存在条件: 继承关系 方法需要重写 ,父类引用指向了类对象! father f1 =new Son();
不可重写:1.static 2.final 3.private
package Demo06;
public class Person {
public void run(){
System.out.println("run");
}
public void cry(){
System.out.println("哭");
}
}
package Demo06;
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("吃");
}
}
package Method;
import Demo06.Person;
import Demo06.Student;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//如 new Student new Person
//可以指向的引用类型就不确定了:父类的引用指向子类
//子类 可以调用自己的方法 或者继承父类的
//父类 可以指向子类 但不能调用子类独有的方法
Student st1 =new Student();
Person st2=new Student();
//对象能执行哪些方法 主要看对象左边的类型
st2.run();//子类重写了父类的方法,执行子类的方法
st1.run();
st1.eat();
st1.cry();//父类可以继承的方法 可以使用
st2.cry();//如果是父类特有 执行自己的方法
((Student) st2).eat();//强制类型转换 子类特有 父类无法使用
}
}
son
son
吃
哭
哭
吃
instanceof
instanceof (类型转换 ) 引用类型 判断一个对象是什么类型
package Method;
import Demo06.Person;
import Demo06.Student;
import Demo06.Teacher;
public class Application {
public static void main(String[] args) {
// Object>String
//Object>Person>Student
//Object>Person>Teacher
//System.out.println( X instanceof Y);//X Y 是否有继承关系
Object object = new Student();
System.out.println(object instanceof Student);//object 指向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
System.out.println("=========================");
Person object2 = new Student();
System.out.println(object2 instanceof Student);//True
System.out.println(object2 instanceof Person);//True
System.out.println(object2 instanceof Object);//True
System.out.println(object2 instanceof Teacher);//False
//System.out.println(object2 instanceof String); //编译错误
// 感觉是obj的指向类型 判断 true or false
// obj的类型决定能否比较
System.out.println("=========================");
Person object3 = new Person();
System.out.println(object3 instanceof Student);//False
System.out.println(object3 instanceof Person);//True
System.out.println(object3 instanceof Object);//True
System.out.println(object3 instanceof Teacher);//False
//System.out.println(object3 instanceof String); //编译错误
System.out.println("=========================");
Student object4 = new Student();
System.out.println(object4 instanceof Student);//True
System.out.println(object4 instanceof Person);//True
System.out.println(object4 instanceof Object);//True
//System.out.println(object4 instanceof Teacher);//编译错误
//System.out.println(object4 instanceof String); //编译错误
}
}
类型转换
1.父类引用 指向子类的对象
2.子类转化为父类 向上转型 ,可能会丢失自己的一些方法
3.父类转化为子类 向下转型 需强型转换
4.方便代码使用
package Demo06;
public class Person {
public void run(){
System.out.println("run");
}
}
package Demo06;
public class Student extends Person{
public void go(){
System.out.println("go");
}
}
package Method;
import Demo06.Person;
import Demo06.Student;
import Demo06.Teacher;
public class Application {
public static void main(String[] args) {
//类型之间的转化: 父 子
//高 低
Person obj =new Student();
//obj.go();编译报错 无法使用
//student 将这个obj转化为Student 则go可以使用
//父类Person 转化为子类 Student
Student student =(Student) obj;
student.run();
student.go();
((Student)obj).go();
//子类转换为父类,可能会丢失自己的一些方法
Person person = student;
//person.go(); 无法使用
}
}
run
go
go
抽象类
abstract
package Demo05;
//抽象类: 类 extends: 单继承~ (接口可以多继承)
public abstract class Action {
//约束 有人帮我们实现
//抽象方法 只有方法名字 没有方法的实现
public abstract void doSomeThing();
//约束 不能new产生 必须通过子类来实现它
//抽象类中可以写普通方法
//抽象方法必须在抽象类中
public void say(){
System.out.println("say");
}
//抽象的抽象 约束
//思考题? 不能 new 存在构造器吗 以及 存在的意义 抽象出来 提高开发效率
}
package Demo05;
//抽象类的所有方法 继承了他的子类 都必须重写它的抽象方法
public class A1 extends Action{
@Override
public void doSomeThing() {
}
}
class文件
package Demo05;
public abstract class Action {
public Action() {
}
public abstract void doSomeThing();
public void say() {
System.out.println("say");
}
}
说明有 构造器
接口
普通类:只有具体实现 抽象类:具体实现和规范 接口:只有规范!自己无法写方法
面向接口编程 实现约束和实现分离
接口本质是契约 interface关键字
package Demo02;
public interface UserService {
//可以常量 public static final
int AGE =99;
//接口中的所有定义都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package Demo02;
public interface TimeService {
void timer();
}
package Demo02;
//抽象类: expends
//类 可以实现接口 implements 接口
//实现接口的类 就需要重写类中的方法 alt+enter
public class UserServiceImp 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() {
}
}
作用:
1.约束
2.定义一些方法 让不同人来实现
3.public abstract
4.public static final
5.接口不能被使用 接口中没有构造方法
6.implement可以实现多个接口
7.必须重写接口的方法
内部类
成员内部类
package Demo3;
public class Outer {
private int id;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
public void getId(){
System.out.println(id);
}
}
}
package Demo3;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过外部类来实例化 内部类
Outer.Inner inner= outer.new Inner();
inner.in();
inner.getId();
}
}
这是内部类的方法
0
内部类 外部类 重名时 优先访问内部类 使用 outer.this 调用
内部类不能包含static 可以包含 static final
静态内部类 static只能修饰内部类
public static class Inner{}
//public void getId() 无法在获得外部类私有属性id 除非 id 也为static
package D1;
public class Outer01 {
private String name = "外部类";
private int age = 18;
static class Inner{
private String name ="内部类";
private int size = 100;
private static int count = 0;
public void show(){
//调用Outer
Outer01 outer01 = new Outer01();
System.out.println(outer01.name);//访问外部类属性
System.out.println(name);//内部类属性
System.out.println(count);
System.out.println(Inner.count);
}
}
}
package D1;
public class Test01 {
public static void main(String[] args) {
Outer01.Inner inner = new Outer01.Inner();//访问静态成员类 标明外部类
inner.show();
}
}
外部类
内部类
0
0
局部内部类:定义在内部类方法中 故应用范围仅在此方法中
package D1;
public class Outer02 {
private String name = "张三";
private static int age = 10;
public void show(){
String address = "南京";
class Inner{
private String tel = "18888888888";
private String email = "zhangsan@163.com";
public void show2(){
System.out.println(name);//Outer.this.name
System.out.println(age);//Outer.age
System.out.println(tel);//this.tel
System.out.println(email);
//访问方法中的变量 只能访问常量 jdk1.7之前 需要加上final 1.8之后默认
System.out.println(address);
}
}
//address = "深圳"; 此处若修改 Inner类中将无法使用 address 因为 address不为常量了
Inner inner = new Inner();
inner.show2();
}
}
package D1;
public class Test02 {
public static void main(String[] args) {
Outer02 outer02 = new Outer02();
outer02.show();
}
}
张三
10
18888888888
zhangsan@163.com
南京
匿名内部类 : 必须继承一个接口或者父类
public static void main(String[] args){
Usb usb = new Usb{
@override
public void show(){
System.out.println("匿名内部类");
}
}
usb.show();
}