面向对象
什么是面向对象
面向对象思想:物以类聚,分类的思维方式。面向对象适合处理复杂的问题,适合处理需要多人协作的问题
属性+方法=类
面对象的本质:以类的方式组织代码,以对象的组织(封装)数据。
三大特性:
- 封装
- 继承
- 多态
回顾方法及加深
方法的定义:
- 修饰符
- 返回类型
- break:跳出switch,结束循环。return:结束方法
- 方法名:注意规范:驼峰原则。见名知意
- 参数列表:参数类型 ,参数名
- 异常抛出
//Demo01 类
public class Demo01 {
//main 方法
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名(···){
//方法体
return 返回值;
}
*/
public String sayHello(){
return "hello World!";
}
public void hello(){
return;
}
public int max(int a,int b){
return a>b?a:b;//三元运算符
}
public void readFile(String file) throws IOException {
}
}
回顾方法的调用
-
静态方法
-
非静态方法
//学生类
public class Student {
//非静态方法
public void say(){
System.out.println("学生说话了!");
}
}
public class Demo02 {
public static void main(String[] args) {
//实例化这个类 new
//对象类型 对象名 = 对象值
Student student = new Student();
student.say();
}
//和类一起加载的
public static void a(){//加了static
}
//类实例化之后 才存在的
public void b(){
a();
}
}
- 形参和实参
public class Demo03 {
public static void main(String[] args) {
//实际参数和形式参数的类型对应
new Demo03().add(1,2);
}
public int add(int a,int b){
return a+b;
}
}
- 值传递和引用传递
Java里都是值传递
//值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);
Demo04.change(a);
System.out.println(a);
}
public static void change(int a) {
a = 10;
}
}
//引用传递:对象,本质还是值传递
public class Demo05 {
public static void main(String[] args) {
Perosn a = new Perosn();
System.out.println(a.name);//null
Demo05.change(a);
System.out.println(a.name);//wanglong
}
public static void change(Perosn perosn){
//perosn是一个对象,指向的是 Perosn perosn = new Perosn();这是一个具体的人,可以改变属性
perosn.name="wanglong";
}
}
//一个类里面只有一个public class,可以有多个class
//定义了一个perosn类,有一个属性:name
class Perosn{
String name;
}
类与对象的创建
//学生类
public class Student {
//属性:字段
String name;//null
int age;//0
//方法
public void study(){
System.out.println(this.name+"在学习");//this指代自己这个类
}
}
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//类是抽象的,需要实例化
//类实例化后会返回一个自己的对象
//student 对象就是一个Student类的具体实例
Student xiaoming = new Student();
Student xh = new Student();
xiaoming.name="小明";
xiaoming.age=3;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
xh.name="小红";
xh.age=3;
System.out.println(xh.name);
System.out.println(xh.age);
}
}
构造器详解(重要)
类中的构造器也叫构造方法,是在进行创建对象的时候必须要调用的
- 必须和类的名字相同
- 必须没有返回类型,也不能写void
构造器作用:
- new本质在调用构造方法
- 初始化对象的值
注意点:
- 定义了有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
- Alt+Insert+Fn:快捷键,鼠标右键里面也有
public class Person {
//一个类即使什么也不写,也会存在一个方法
//显示的定义一个构造器
String name;
//实例化初始值
//1.使用new关键字,必须使用构造器
//2.构造器用来初始化值
public Person(){
this.name="wanglong";
}
//有参构造:一旦定义了有参构造,无参必须显示定义
public Person(String name){
this.name=name;
}
//记住alt+Insert 还要+Fn用来生成构造器
}
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//new 实例化了一个对象
Person person = new Person("王龙");
System.out.println(person.name);
}
}
创建对象内存分析
public class Pet {
public String name;
public int age;
//默认有无参构造
public void shout(){
System.out.println("叫了一声");
}
}
public class Application {
public static void main(String[] args) {
Pet dog=new Pet();
dog.name="旺财";
dog.age=3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet cat =new Pet();
}
}
简单小结
- 类与对象
类是一个模板,抽象,对象是一个具体的实例
- 方法
定义、调用
- 对应的引用
引用类型:除了基本类型(8)
对象通过引用来操作:栈(引用变量名)-->堆(地址,实际的地方)
- 属性:字段Filed 成员变量
默认初始化:数字: 0 0.0
char:u0000
boolean:false
引用:null
修饰符 属性类型 属性名 = 属性值
-
对象的创建和使用
- 必须使用new 关键字创造对象,构造器 Person wanglong = new Person();
- 对象的属性 wanglong.name
- 对象的方法 wanglong.sleep()
-
类
静态的属性 属性
动态的行为 方法
封装、继承、多态
封装
追求:高内聚,低耦合
属性私有,get/set:快捷键:Alt+insert
//类 private 私有
public class Student {
//属性私有
private String name;
private int id;
private int age;
private char sex;
//提供一些可以操作这个属性的方法
//提供一些public 的 get、set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个属性设置值
public void setName(String name){
this.name=name;
}
//Alt+insert 可以快速生成
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<120&&age>0){
this.age = age;
}
else//不合法
this.age=3;
}
}
//封装的意义:
//提高代码的安全性,保护数据
//隐藏代码的实现细节
//统一接口
//系统的可维护性增加了
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
String name = s1.getName();
s1.setName("wanglong");
System.out.println(s1.getName());
s1.setAge(999);//不合法的
System.out.println(s1.getAge());
}
}
继承
继承本质是对某一些类的抽象
extends:扩展,子类对父类的扩展
Java中只有单继承,没有多继承!
//java中所有的类,都默认直接或者间接继承Object,
//Person 人 父类
public class Person {
//public 公共的
//private 私有的
private int money=10_0000_0000;
public void say(){
System.out.println("说了一句话");
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
//学生 is 人 子类,派生类
public class Student extends Person{
//Ctrl+H
}
//Teacher is 人 子类 派生类
public class Teacher extends Person {
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.getMoney());
Person person = new Person();
}
}
super
super - this一个表示父一个表示当前的
super注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中
- super和this不能同时调用构造方法
this:
- this:本身调用者这个对象。super:代表父类的引用
- this:没有继承也可以使用,super:只能在继承条件下才可以使用
- this();调用本类的构造
- super();调用的是父类的构造
public class Person {
public Person() {
System.out.println("Person无参执行了");
}
protected String name ="wanglong";
//私有的东西不能被继承
private void print1(){
System.out.println("Person");
}
public void print(){
System.out.println("Person");
}
}
public class Student extends Person{
public Student() {
//隐藏代码:调用了父类的无参构造
// super();//调用父类的构造器,必须要在子类构造器的第一行
System.out.println("Student无参执行了");
}
public Student(String name) {
this();
this.name = name;
}
private String name ="qqq";
public void print(){
System.out.println("Student");
}
public void test1 (){
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 > Protected > Default > private
- 抛出的异常:范围可以被缩小,但不能扩大。ClassNotFoundException-->Exception(大)
重写,子类的方法和父类必须要一致,但是方法体不同
为什么需要重写?
-
父类的功能,子类不一定需要,或者不一定满足。
Alt+Insert:选中override;(快捷键)
//重写都是方法的重写,和属性无关
public class B {
public void test(){
System.out.println("B=>test()");
}
}
public class A extends B {
//Override:重写
@Override//注解:有功能的注释
public void test() {
System.out.println("A=>test()");
}
}
public class Application {
//静态的方法和非静态的区别很大
//静态方法://方法的调用只和左边,就是定义的数据类型有关
//非静态方法:重写
public static void main(String[] args) {
A a =new A();
a.test();//A
//父类的引用指向了子类
B b=new A();//子类重写了父类的方法
b.test();//B
}
}
多态
动态编译:类型:可扩展性
即同一个方法可以根据发送对象的不同采用不同的行为方式
- 多态是方法的多态,属性没有多态
- 父类和子类,有联系 类型转化异常 ClassCastException
- 存在条件:继承关系,方法需要重写,父类的引用指向子类对象! Father f1= new Son()
哪些方法不能重写:
- static 方法,属于类,不属于实例
- final 常量
- private方法:私有的
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");
}
}
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
// new Student();
// new Person();
//可以指向的引用类型就不确定了 父类的引用指向子类
//Student 能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
//Person 父类型,可以指向子类,但是不能调用子类独有的方法
Person s2 = new Student();//父类的引用指向子类的类型
Object s3 = new Student();
//能执行那些方法,主要看对象左边的类型,,和右边关系不大!
s2.run();//子类重写了父类的方法,执行子类的方法
s1.run();
//s2.eat();
((Student)s2).eat();//强制转换,,,高转低
}
}
instanceof和类型转换
public class Application {
//Object > String
//Object > Person > Teacher
//Object > Person > Student
public static void main(String[] args) {
Object obj = new Student();
//System.out.println(X instanceof Y);能不能编译通过,取决于X和Y直接有没有父子关系,X的实际类型和后面的比较
System.out.println(obj instanceof Student);//true
System.out.println(obj instanceof Person);//true
System.out.println(obj instanceof Object);//true
System.out.println(obj instanceof Teacher);//false
System.out.println(obj instanceof String);//false
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);编译就报错
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(person instanceof String);编译就报错
}
}
- 父类的引用指向子类的对象
- 子类转化为父类,向上转型,直接转化
- 父类转化子类,向下转型,强制转换
- 方便方法的调用,减少重复的代码
public class Application {
public static void main(String[] args) {
//类型之间的转化:父 子
//高 低
Person obj = new Student();
//student 将这个对象转化为Student类型,我们就可以使用Student类型的方法了
Student student =(Student) obj;
student.go();
//高转低强制转换,低转高自动转化
Student student1=new Student();
Person person=student1;//子类转化为父类,可能丢失一些自己本来的方法
}
}
static关键字
//静态导入包
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 修饰了类之后,不能有子类了
//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);不可以,score非static字段
System.out.println(s1.age);
System.out.println(s1.score);
Student.go();
go();
}
public void run(){
go();
}
public static void go(){
}
}
public class Person {
{//赋初始值
//代码块(匿名代码块)
System.out.println("匿名代码块");
}
static {//只执行一次
//静态代码块
System.out.println("静态代码块");
}
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("============");
Person person2 = new Person();
}
}
抽象类
//abstract 抽象类 类 extends :单继承 (接口可以多继承)
public abstract class Action {
//约束 有人帮我们实现
//abstract,抽象方法,只有方法名字,没有方法的实现
public abstract void doSomething();
//不能new这个抽象类,只能靠子类去实现它:约束
//抽象类中可以写普通方法
//抽象方法必须在抽象类中
//抽象的抽象:约束
public Action() {
}
}
//抽象类的所有方法,继承了它的子类,都必须要实现它的方法 除非子类也是抽象类
public class A extends Action{
@Override
public void doSomething() {
}
}
接口的定义和实现
普通类:只有具体实现
抽象类:具体实现和抽象方法都有
接口:只有规范,自己无法写方法,专业的约束,约束和实现分离
接口声明的关键字:interface
接口的作用:
- 约束
- 定义一些方法,让不同的人实现
- 方法都是public abstract
- 常量都是:public static final
- 接口不能被实例化,接口中没有构造方法
- implement可以实现多个接口
- 必须要重写接口中的方法
N种内部类
内部类就是在一个类的内部再定义一个类。
一个Java文件可以有多个class类,但是只有一个public class
成员内部类
public class Outer {
private int id=10;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
}
局部内部类
public class Outer {
//局部内部类
public void method(){
class Inner{
public void in(){
}
}
}
}
public class Test {
public static void main(String[] args) {
//没有名字的初始化类,不用将实例保存在变量中
new Apple().eat();
//匿名内部类
new UserService() {
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
标签:Java,void,System,面向对象,Student,println,public,out
From: https://www.cnblogs.com/shijili/p/18000130