所有学习内容来自:狂神说java
一、面向对象编程
面向对象&面向过程
什么是面向对象:
二、方法回顾
值传递和引用传递:
引用类型如类、数组等输入方法后是引用传递,在方法中改变其内部的值会导致方法外也改变;int等基本类型是值传递,不改变方法外的值。
// 引用传递
public class Demo05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
Demo05.change(person);
System.out.println(person.name);
}
public static void change(Person person){
person.name = "CYJ";
}
}
// 定义了一个person类,有一个属性:name
class Person{
String name;
}
三、类和对象的关系
类和对象的关系
一个项目应该只有一个main方法
面向对象的本质就是:以类的方式组织代码, 以对象的方式组织(封装)数据
// 一个项目应该只有一个main方法
public class Application {
public static void main(String[] args) {
// 类是抽象的,需要实例化
// 类实例化后会返回一个自己的对象
// student 对象就是一个Student类的具体实例!
Student xiaoming = new Student();
Student xiaohong = new Student();
xiaoming.name = "xiaoming";
xiaoming.age = 3;
xiaohong.name = "xiaohong";
xiaohong.age = 3;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
System.out.println(xiaohong.name);
System.out.println(xiaohong.age);
}
}
// 学生类
public class Student {
// 属性:字段
String name;// 默认值null
int age;// 默认值0
// 方法
public void study(){
System.out.println(this.name+"在学习");
}
}
// Person-->身高,体重,年龄,身高……
构造器
public class Person {
// 查看class文件可以发现
// 一个类即使什么都不写,它也会存在一个方法
// 显示的定义构造器
String name;
// 实例化初始值
// 1.使用 new()关键字,本质是在调用构造器
// 2.用来初始化值
// 无参构造
// public Person(){
// this.name = "cyj";
// }
//
// // 有参构造:一但定义了有参构造,无参就必须显示定义
// public Person(String name){
// this.name = name;
// }
//alt + insert 快捷键可以快速生成构造
public Person(String name) {
this.name = name;
}
}
/*
public class Application {
public static void main(String[] args) {
// 实例化了一个对象
Person person = new Person("kuangshen");
System.out.println(person.name);
}
}
构造器:
1. 和类名相同
2.没有返回值
作用:
1. new本质是在调用构造方法
2. 初始化对象的值
注意点:
1. 定义有参构造之前,如果想使用无参构造,需要显示的定义一个无参构造
快捷键:
Alt + Insert
*/
创建对象内存分析
小结
-
类与对象
类是一个模板: 抽象;对象是一个具体的实例
-
方法
定义、调用
-
对象的引用
引用类型 基本类型
对象是通过引用来操作的:栈-->堆
-
属性: 字段 Field 成员变量
默认初始化:
数字:0, 0.0
char:u0000
boolean:false
引用:null
修饰符 属性类型 属性名 = 属性值
-
对象的创建与使用
必须使用new 关键字创造对象,构造器 Person kuangshen = new Person();
对象的属性 kuangshen.name
对象的方法 kuangshen.sleep()
-
类
静态的属性 属性
动态的行为 方法
四、面向对象的三大特性
封装、继承、多态
封装
// 类 private:私有
public class Student {
// 属性私有
// 属性: 名字、学号、性别、
private String name;
private int id;
private char sex;
private int age;
// 方法 学习()、 睡见()
// 提供一些可以操作这个属性的方法!
// 提供一些public的get、set方法
// get 获得这个属性
public String getName(){
return this.name;
}
// set 给这个数据设置值
public void setName(String name){
this.name = name;
}
// Alt + Insert
public int getId() {
return id;
}
public char getSex() {
return sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/*
public class Application {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("Cai");
System.out.println(stu1.getName());
stu1.setAge(999);
System.out.println(stu1.getAge());
}
}
*/
封装的目的:
1.提升程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护性增加了
继承
object类
public class Person {
// public 的才能继承
// protected
// default
// private 无法被调用
private int money = 10_0000_0000;
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void say(){
System.out.println("说了一句话");
}
}
在Java中所有类都默认直接或者间接继承了Object类
super(-this)
super注意点:
1.super是调用父类的构造方法,必须在构造方法的第一个
2.super必须只能出现在子类的方法或者构造方法中!
2.super和this不能同时调用构造方法
VS this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也能使用
super:只能在继承条件才能使用
构造方法:
this();本类的构造
super();父类的构造
举例:
public class Stutent extends Person {
public Stutent() {
//隐藏代码:默认先调用了父类的无参构造
super("Cai");// 调用父类构造器,必须在第一行
System.out.println("Student无参执行了");
}
private String name = "Cai";
public void test1(String name){
print();// 当前类
this.print();// 当前类
super.print();// 父类
}
public void test(String name){
System.out.println(name);
System.out.println(this.name);// 当前类中的属性
System.out.println(super.name);// 父类中的属性
}
public void print(){
System.out.println("Student");
}
}
/*
public class Person {
public Person() {
}
public Person(String name) {
System.out.println("Person无参执行了");
}
protected String name = "dirtywater";
public void print(){
System.out.println("Person");
}
}
*/
方法的重写(重点-->多态)
重写都是方法的重写。
重写:(需要有继承关系,子类重写父类的方法)
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以扩大:public>protected>default>private
4.抛出的异常:范围可以被缩小,但不能扩大;ClassNotFoundException --> Exception(大)
重写:子类方法和父类必须要一致,方法体不同!
为什么需要重写:
1.父类的功能,子类不一定需要,或者不一定满足!
Alt + Insert :override
举例:
public class A extends B {
// public void test(){
// System.out.println("A=test");
// }
// 重写 alt + insert 快捷键
@Override// 注解:有功能的注释
public void test() {
System.out.println("A=test");
}
}
/*
// 重写都是方法的重写
public class B {
public void test(){
System.out.println("B=test");
}
}
*/
public class Application {
// 静态方法和非静态方法区别很大!
// 静态方法: 方法的调用只和左边(定义的数据类型)有关
// 子类不能重写父类中声明为final和static的方法
// 非静态:重写(只能是public类)
public static void main(String[] args) {
// 方法的调用只和左边(定义的数据类型)有关
A a = new A();
a.test();
// 父类的引用会指向子类
B b = new A();// 子类重写了父类的方法
b.test();// B //如果是static方法,则输出为B=test;若非static则为A=test
}
}
多态
多态注意事项:
1.多态是方法的多态,属性的多态;
2.父类和子类,有联系 (类型转换异常)ClassCastException!
3.存在的条件:继承关系,方法需要重写(不然多态没有意义),父类引用指向子类对象
不能重写的方法:
1.static方法,属于类,不属于实例
2.final 常量池,
3.private 私有方法
举例:
public class Student extends Person {
@Override
public void run() {
System.out.println("son!");
}
public void eat(){
System.out.println("eat!");
}
}
/*父类
public class Person {
public void run(){
System.out.println("run!");
}
}
*/
/*项目执行
public class Application {
public static void main(String[] args) {
// 一个对象的实际类型是确定的,但是可以指向的引用类型就不确定了
// Student 能调用的方法都是自己的或者继承父类的
Student stu1 = new Student();
// Person父类型,可以指向子类,但是不能调用子类独有的方法
Person stu2 = new Student();// 父类的引用指向子类的类型
Object stu3 = new Student();
stu1.run();
stu2.run();// 执行的是Student中重写后的run()方法
// stu2.eat();
stu1.eat();
((Student) stu2).eat();// 强制类型转换,高转低
// 能调用哪些方法,是引用决定的;具体执行哪个方法,是引用指向的对象决定的
// 对象能执行哪些方法,主要看对象左边的类型
}
}
*/
instanceof (类型转换)
引用类型,判断一个对象是什么类型
instansof 类型转换:
1.父类引用指向子类的对象
2.把父类转换为父类,向上转型
3.把父类转换为子类,向下转型;强制转换
4.方便方法的调用,减少重复的代码!
抽象:封装、继承、多态! 抽象类
举例:
public static void main(String[] args) {
// Object > String
// Object > Person > Student
// Object > Person > Teacher
// System.out.println(X instanceof Y);// 能不能编译通过!看存不存在父子关系
Object object = new Student();
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
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);// 编译报错
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);// 编译报错
// System.out.println(student instanceof String);// 编译报错
}
类型转换:
public static void main(String[] args) {
// 类型之间的转换:父类(高) 子类(低)
Person stu1 = new Student();
// stu1这个对象转换为Student类型,就可以使用Student类型的方法了
((Student) stu1).go();
Student stu2 = new Student();
stu2.go();
Person person = stu2;
// person.go();
// 子类转换为父类可能会丢失自己本来的一些方法
}
static关键字
代码块:
public final class Person { // 用final修饰的类不能被继承
// 2.赋初值
{
//代码块(匿名代码块)
System.out.println("匿名代码块");
}
// 1.只执行一次
static {
System.out.println("静态代码块");
}
// 3.
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person per1 = new Person();// 静态代码块 --> 匿名代码块 --> 构造方法
System.out.println("==============================");
Person per2 = new Person();// 匿名代码块 --> 构造方法
}
}
静态变量和方法:
public class Student {
private static int age;// 静态变量 多线程!
private double score;// 非静态变量
public static void main(String[] args) {
Student stu1 = new Student();
System.out.println(Student.age);
System.out.println(stu1.age);
System.out.println(stu1.score);
Student.go();
stu1.run();
}
public void run(){
}
public static void go(){
}
}
静态导入包:
// 静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
public static void main(String[] args) {
System.out.println(Math.random());
System.out.println(PI);
}
}
五、抽象类和接口
抽象类
// abstract 抽象类:类
// extends:单继承(接口可以实现多继承)
public abstract class Action {
// 约束-有人帮我们实现
// abstract,抽象方法,只有方法名字,没有方法内容
public abstract void doSomeThing();
// 1.不能new抽象类,只能靠子类去实现,抽象类是一个约束!
// 2.抽象类中可以写普通方法
// 3.抽象方法必须写在抽象类中
// 思考题? 抽象类不能new对象,那存在构造器吗?
// 答:是存在构造器的,因为可以在抽象类中添加构造器,并且在子类中调用
// 存在的意义? 框架设计和协同,提高开发效率
public Action() {
}
public Action(String name) {
System.out.println(name);
}
}
/*
// 继承抽象类必须要重写其中的方法,除非子类也是抽象类
public class A extends Action {
public A(String name) {
super(name);
}
@Override
public void doSomeThing() {
System.out.println("DO");
}
}
*/
接口
自己无法写方法,是一个专业的约束!实现约束和接口分离:面向接口编程。
接口的本质是契约
接口的作用:
1. 约束
2. 定义一些方法来让不同的人实现
3. 接口中定义的所有方法都是 public abstract
4. 定义的属性都是常量 public static final
5. 接口不能被实例化,接口中没有构造方法
6. implements可以实现多个接口
7. 子类必须要重写接口中的方法
举例:
// 抽象类:extends,单继承
// 类可以实现接口,implements 接口,利用接口可以实现多继承
// 实现接口中的类,必须要重写接口中的所有方法
public class UserServiceImpl implements UserService, TimeService{
@Override
public void timer() {
}
@Override
public void add(String name) {
}
}
/* 接口1
// interface 定义的关键字
public interface UserService {
// 定义的属性都是常量 //一般不会在接口中定义常量
int AGE = 99;
// 接口中定义的所有方法都是 public abstract
void add(String name);
}
*/
/* 接口2
public interface TimeService {
void timer();
}
*/
六、内部类及oop实战
内部类
内部类的实例化和使用:
public class Outer {
private int id = 10;
public void out(){
System.out.println("这是外部类方法");
}
public static class Inner{
public void in(){
System.out.println("这是内部的方法");
}
// // 获得外部类的私有属性,加了static就无法调用了,因为static在实例化之前就存在,除非外部变量也是static
// public void gerID(){
// System.out.println(id);
// }
}
}
// 一个java文件中可以有多个class,但是只能有一个public class
class A{
public static void main(String[] args) {
}
}
/*
public static void main(String[] args) {
Outer outer = new Outer();
Test test = new Test();
// 通过外部类来实例化内部类
// Outer.Inner inner = outer.new Inner();
// inner.in();
}
*/
一些内部类的举例:
public class Test {
public static void main(String[] args) {
// 没有名字去初始化类,不用将实例保存到变量中
new Apple().eat();
UserService userService = new UserService(){
@Override
public void hello() {
}
};
}
public void method(){
// 局部内部类
class Inner2{
public void inin(){}
}
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
标签:name,void,System,Day06,面向对象编程,println,public,out
From: https://www.cnblogs.com/d1rtywatersblog/p/17838053.html