JAVA基础(九)面向对象
一、面向过程&面向对象
方法—>结构体—>类
1、面向过程
线性思维
2、面向对象(OO)
分类的思维模式
面向对象编程(OOP):以类的方式组织代码,以对象的组织(封装)数据。
三大特性:封装,继承,多态
二、方法
1、方法的定义
public class demo01 {
//主函数
public static void main(String[] args) {
}
/*
修饰符 返回值类型 方法名(...){
//方法体
return 返回值;
}
*/
public String sayhello(){
return "hello";
}
public void print(){
return;
}
public int max(int a,int b){
return a>b?a:b;
}
}
2、方法的调用
- 静态方法可以调用静态方法; //static的方法是和类一起加载的
package com.kang.oop;
public class demo02 {
public static void main(String[] args) {
Student.sayhello();
}
}
package com.kang.oop;
public class Student {
public static void sayhello(){
System.out.println("hello");
}
public void print() {
return;
}
}
- 静态方法调用非静态方法,需要先将非静态方法实例化;
//对象类型 对象名 = 对象值;
package com.kang.oop;
public class demo02 {
public static void main(String[] args) {
Student student =new Student(); //对象类型 对象名 = 对象值;
student.sayhello();
}
}
package com.kang.oop;
public class Student {
public void sayhello(){
System.out.println("hello");
}
public void print() {
return;
}
}
3.值传递
package com.kang.oop;
public class demo03 {
public static void main(String[] args) {
int a=1;
System.out.println(a);
change(a);
System.out.println(a);//java中是值传递,a的值实际没有改变
}
public static int change(int a){
return a=10;
}
}
4.引用传递
package com.kang.oop;
//引用传递
public class demo05 {
public static void main(String[] args) {
Person person=new Person();
System.out.println(person.name);
demo05.changename(person);
System.out.println(person.name);
}
public static void changename(Person person){
//person是一个对象,相应的---> Person person = new Person();这是一个具体的人,可以改变属性!
person.name="葛宝康";
}
}
class Person{
String name;
}
三、类和对象的创建
package com.kang.oop.Demo02;
//学生类
public class Student {
//属性
String name;
int age;
//方法
public void study(Student student){
System.out.println(student.name+"在学习");
}
}
package com.kang.oop.Demo02;
public class Application {
public static void main(String[] args) {
//类:抽象的 , 实例化
//类实例化后返回一个自己的对象
//student对象是一个Student类的具体实例!
Student gbk = new Student();
Student liutao = new Student();
gbk.name="葛宝康";
gbk.age=22;
System.out.println(gbk.name);
System.out.println(gbk.age);
liutao.name="刘涛";
liutao.age=18;
System.out.println(liutao.name);
System.out.println(liutao.age);
}
}
四、构造器(默认自带)
1、使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
2、
package com.kang.oop.Demo02;
public class Application01 {
public static void main(String[] args) {
Person person=new Person();
}
}
package com.kang.oop.Demo02;
public class Person {
//一个类即使什么都不写,它也会存在一个方法,方法名与类同名
// 显示的定义构造器
String name;
//构造器作用:
//1、使用new关键字必须要有构造器 ,new本质上实在调用构造器
//2、用来初始化
public Person(){
***** //初始化后person.name=null;
}
//有参构造:一旦定义了有参构造,无参构造必须显示定义
public Person(String name){
this.name = name;
}
}
快捷键:Alt+Ins。生成无参构造
总结:
/*
构造器:
1.和类名相同
2.没有返回值
作用:
1. new本质在调用构造方法
2.初始化对象的值
注意点:
1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
快捷键:Alt + Insert
this.*** = 传入的参数
*/
五、创建对象分析
ps:方法区也属于堆
六、小结
/*
1.类与对象
类是一个模板: 抽象,对象是一个具体的实例
2.方法
定义、调用!|
3.对象的引用
引用类型:基本类型(8)
对象是通过引用来操作的:栈--->堆
4.属性:字段Field 成员变量
默认初始化:
数字:0.0char : u0000boolean:false引用: null
修饰符﹑属性类型属性名=属性值!
5.对象的创建和使用
-必须使用new关键字创造对象,构造器Person kuangshen = new Person( );
-对象的属性kuangshen.name
-对象的方法kuangshen.sleep()
6.类:
静态的属性 属性
动态的行为 方法
<封装、继承、多态>
*/
补充:对象和对象的引用。https://www.cnblogs.com/hukai46/p/5258668.html)
七、封装
1、高内聚,低耦合(内部细节自己做,少量方法外部用)
总之记住:属性私有(private),get/set**
package com.kang.oop.Demo03;
import com.kang.oop.Demo03.Student;
/* 1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护增加了
*/
public class Application {
public static void main(String[] args) {
Student gbk = new Student();
gbk.setAge(18);
System.out.println(gbk.getAge());
}
}
package com.kang.oop.Demo03;
public class Student {
private int age;
private String name;
private char sex;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
//生成get/set方法快捷键: alt+instert
}
可以在get/set方法中添加条件。
八、继承
1.继承树快捷键:ctl+h
2.JAVA中只有单继承,没有多继承。(一个儿子只有一个爸爸,一个爸爸有多个儿子)
3.继承extends
package com.kang.oop.Demo04;
public class Person {
private int age;
public String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("你好!");
}
}
package com.kang.oop.Demo04;
public class Student extends Person{
}
package com.kang.oop.Demo04;
public class Application {
public static void main(String[] args) {
Student gbk = new Student();
gbk.name="葛宝康";
System.out.println(gbk.name);
gbk.setAge(18);
System.out.println(gbk.getAge());
gbk.say();
}
}
4.系统默认带有Object类,且所有类都继承了Object类。可以调用Object类中的属性、方法。
5.Super方法详解
super.*** 调用父类方法;
(1)super.* 案例
package com.kang.oop.Demo05;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test1();
}
}
package com.kang.oop.Demo05;
public class Person {
protected String name="gbk";
public void print(){
System.out.println("person");
}
}
package com.kang.oop.Demo05;
public class Student extends Person {
private String name="gebaokang";
public void print(){
System.out.println("student");
}
public void test1(){
print();
this.print();
super.print();
}
}
(2)子类无参构造也会调用父类无参构造
package com.kang.oop.Demo05;
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
package com.kang.oop.Demo05;
public class Person {
public Person(){
System.out.println("Person无参执行");
}
}
package com.kang.oop.Demo05;
public class Student extends Person {
public Student(){
System.out.println("Student无参执行");
}
}
(3)子类的无参构造函数调用父类的有参构造
package com.kang.oop.Demo05;
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
package com.kang.oop.Demo05;
public class Person {
public Person(String name){
System.out.println("Person无参执行");
}
package com.kang.oop.Demo05;
public class Student extends Person {
public Student(){
super("gbk");
System.out.println("Student无参执行");
}
tips:一旦自定义了构造函数(无论是不是有参构造函数),默认个的无参构造都会失效,只能自己重载一个无参构造。
(4)小结
super注意点:
1. super调用父类的构造方法,必须在构造方法的第一个
2. super 必须只能出现在子类的方法或者构造方法中!
3. super和 this 不能同时调用构造方法!
Vs this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提
this:没有继承也可以使用
super:只能在继承条件才可以使用
构造方法
this();本类的构造
super():父类的构造!
6.方法的重写
(1)
package com.kang.oop.Demo06;
public class Application {
public static void main(String[] args) {
A a=new A();
B b=new B();
a.test();
b.test();
}
}
package com.kang.oop.Demo06;
public class B {
public void test(){
System.out.println("B=>test");
}
}
package com.kang.oop.Demo06;
public class A extends B{
public void test() {
System.out.println("A=>test");
}
}
(2)AB中有无static比较
package com.kang.oop.Demo06;
public class Application {
public static void main(String[] args) {
A a=new A();
B b=new A();//父类的引用指向了子类。由此可见static的方法,其调用结果与B b=new A(),右边无关,只与左边有关。
/*子类对象可以赋给声明为父类的变量:B b = new A();
只不过这样的话,b 就只能调用父类B中声明的方法,属性等,不能调用子类A中的方法、属性。
*/
a.test();
b.test();
}
}
package com.kang.oop.Demo06;
public class B {
public static void test(){
System.out.println("B=>test");
}
}
package com.kang.oop.Demo06;
//重写是方法的重写,与属性无关
public class A extends B{
public static void test() {
System.out.println("A=>test");
}
}
(3)无static,方法的重写
package com.kang.oop.Demo06;
public class Application {
//静态的方法和非静态的方法区别很大!
//静态方法: //方法的调用只和左边,定义的数有关
//非静态:重写 。静态没有重写
public static void main(String[] args) {
A a=new A();
//父类的引用指向了子类
B b=new A();//子类重写了父类的方法
a.test();
b.test();
}
}
package com.kang.oop.Demo06;
public class B {
public void test(){
System.out.println("B=>test");
}
}
package com.kang.oop.Demo06;
//重写是方法的重写,与属性无关
public class A extends B{
//Override 重写
@Override //注释:有功能的注释!
public void test() {
System.out.println("A=>test");
}
}
重写:需要有几成关系。子类重写父类的方法!
1.方法名必须相同
2参数列表必须相同
3.修饰符: 范围可以扩大 但不能缩小 public > protected > Default > private
4.抛出的异常: 范围,可以被缩小,但不能扩大:
重写:子类的方法和父类必须一致 :方法体不同!
为什么需要重写:
1.父类的功能:子类不一定需要,或者不一定满足!
九、多态性
1.多态是方法的多态,属性没有多态性
多态性:即同一方法可以根据发送对象的不同而采用多种不同的行为方式
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类,有关系的类)
package com.kang.oop.Demo7;
import com.kang.oop.Demo7.Student;
import com.kang.oop.Demo7.Person;
import sun.font.ScriptRun;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
// new Student();
//new Person();
//可以指向的引用类型就不确定了:父类的引用指问了类/
// / Student 能调用的方法都是自己的或者维承父类的!
Student a =new Student();
//Person类型为父类型,可以指向子类,但是不能调用子类独有的方法
Person b = new Student();
Object c = new Student();
a.run();
b.run();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
((Student) b).eat();//子类重写了父类的方法,执行子类的方法
a.eat();
}
}
package com.kang.oop.Demo7;
public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
package com.kang.oop.Demo7;
public class Person {
public void run(){
System.out.println("run");
}
}
/*
多态注意事项:
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系 类型转换异常!ClassCastException
3.存在条件:继承关系,方法需要重写,父类引用指向子类对象! Father f1 =new Son();
不能重写的方法
1.static 方法,属于类,它不属于实例
2.final 常量:
3.private 方法:
*/
2.instanceof (类型转换) 引用类型,判断一个对象是什么类型
package com.kang.oop.Demo08;
public class Application {
public static void main(String[] args) {
//System.out.println( x instance y ); x与y之间有关系才为true或false,如果在指向的一条线则为true,否则为false。没有任何联系则编译报错
//例如Object object = new Student(); 指定的线为 Object > Person > Student
//Object > String
//Object > Person > Teacher
//Object > Person > Student
Object object = new Student();
System.out.println(object instanceof String);//false
System.out.println(object instanceof Person);//true
System.out.println(object instanceof Student);//true
System.out.println(object instanceof Teacher);//false
System.out.println(object instanceof Object);//true
Person person = new Student();
// System.out.println(person instanceof String);//编译报错
System.out.println(person instanceof Person);//true
System.out.println(person instanceof Student);//true
System.out.println(person instanceof Teacher);//false
System.out.println(person instanceof Object);//true
Student student = new Student();
//System.out.println(student instanceof String);//两边没有关系,编译报错
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Student);//true
//System.out.println(student instanceof Teacher);//两边没有关系,编译报错
System.out.println(student instanceof Object);//true
}
}
3.类型转换
父类型强制转换成子类型
子类转换成父类会丢失一些方法,不用强制转换
package com.kang.oop.Demo09;
public class Application {
public static void main(String[] args) {
//类型之间的转换: 父 子
Person obj =new Student();
//将obj类型转换为Student类型,我们就可以使用Student类型的方法了!
((Student)obj).eat();;
Student obj1 = new Student();
//子类转化为父类,可能丢失自己本来的一些方法!
Person person = obj1;
}
}
/*
1、父类引用指向子类的对象
2.把子类转换为父类,网上转型;
3.把父类转换为了类,向下转型;强制转换
4.方便方法的调用,减少重复的代码!简介
封装、继示、多态! 抽象类,接口
*/
4.static关键字详解
(1)静态变量,方法
package com.kang.oop.Demo10;
import java.sql.SQLOutput;
public class Student {
private static int age; //静态变量
private int name; //非静态变量
public void run(){
}
public static void go(){
}
public static void main(String[] args) {
Student student = new Student();
System.out.println(Student.age);
//System.out.println(Student.name); 错误,name为非静态方法
System.out.println(student.age);
System.out.println(student.name);
go(); //因为go()为静态方法,而且main函数在Student类中
student.run();
}
}
(2)
package com.kang.oop.Demo10;
public class Person {
{
System.out.println("匿名代码块");
}
static {
System.out.println("静态代码块");
}
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Person s1 = new Person();
System.out.println("===========");
Person s2 = new Person();
}
}
由此static方法只执行一次
(3)静态导入包
package com.kang.oop.Demo10;
//静态导入包
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);
}
}
(4)静态类不能被继承
public static class Person{
}
// public class Student extends Person{ //错误,静态类不能被继承
}
5.接口的定义与实现
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!自己无法写方法专业的约束!约束和实现分离:面向接口编程
、、package com.kang.oop.Demo11;
public interface UserService {
//接口中的所有定义的方法 其实都是抽象的 public abstract
//常量~ public static final
int AGE =99;
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package com.kang.oop.Demo11;
//抽象类:extends~ 只能单继承
//类 可以实现接口 implements 接口 ,可以多继承
//实现了接口的类,就需要重写接口中的方法~
//多继承~利用接口实现多继承
public class UserServiceImpl implements UserService {
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
}
接口作用:
1.约束
2.定义一些方法,让不同的人实现~10--->1
3. public abstract
4. public static final
5.接口不能被实例化~,接口中没有构造方法~
6. implements可以实现多个接口
7.必须要重写接口中的方法~
8.总结博客!
6.内部类(在一个类的内部再定义一个类)
//一个类中只有一个public class, 但是可以有多个 class
(1)成员内部类
package com.kang.oop.Demo12;
import java.sql.SQLOutput;
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);
}
}
}
package com.kang.oop.Demo12;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类~
Outer.Inner inner= outer.new Inner();
inner.in();
inner.getID();
}
}
(2)静态内部类
(3)匿名内部类
package com.kang.oop.Demo12;
import java.sql.SQLOutput;
public class Test {
public static void main(String[] args) {
//没有名字初始化类,不用将实例保存到变量中~
new Apple().eat();
UserService userService = new UserService() {
@Override
public void hello() {
}
};
}
}
//匿名内部类
class Apple{
public void eat(){
System.out.println("吃苹果");
}
}
interface UserService{
void hello();
}
员内部类
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性~
public void getID(){
System.out.println(id);
}
}
}
package com.kang.oop.Demo12;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类~
Outer.Inner inner= outer.new Inner();
inner.in();
inner.getID();
}
}