面向对象
面向过程语言设计思想
过程:具体步骤
把要完成的一件事情,分成一步一步的步骤,然后完成。
面向过程直接关注流程。
例如:开车
1.开车门()
2.坐进去()
3.关车门()
4.插钥匙()
5.踩油门()
面向对象语言设计思想
首先会宏观的对整个事物进行分析(分类),不关心具体要做什么,而是关心谁(对象)去做。
汽车
开门()
关门()
钥匙()
油门()
人
操作()
先有对象,后有类
对象:指的是一个具体存在的。
特点:1.以分类的方式进行思考和解决问题。
2.面向对象先对整体关系作出分类,然后根据不同的类深入细节的处理。
3.面向对象的思想符合人类的认知习惯。
面向对象与面向过程的区别与联系
面向对象无法取代面向过程,他们是相辅相成的。面向对象关注于从宏观上把握事物之间的关系,在具体到如何实现某个细节时,仍然采用面向过 程的思维方式。面向对象如果离开了面向过程,就无法实现真正的落地,成为无源之水。
Java类
什么是类?
类就是对同一类事物(具体存在的)共有的属性(名词)、行为(动词)的定义(抽象)。
类是一个模板,它描述一类事物的属性和行为的集合。
根据某个类,来创建这个类的具体实例(对象)
类是表示一个客观世界某类群体的特征抽象。
发现类(设计类)
类的结构
成员变量:事物属性的描述;
方法:事物的行为(可以做的事情) ;
构造方法:用于创建对象;
内部类: 即在类体中声明的类;
块:一段没有名称的代码块。
Java对象
对象是类的实例,是概念的具体存在,以类为模板,在内存中创建一个真实存在的实例。
万事万物皆为对象(可以使用的)
public class TextCar {
public static void main(String[] args) {
/*
new 使用new关键字创建一个新的对象
new Car 创建Car类的对象
Car() 使用类的构造方法初始化类
Car bm 声明一个与构造方法相同的类型的变量
= 把内存中对象存储的地址 赋值给左边的 bm变量
*/
Car bm = new Car();
bm.name = "宝马";
bm.color = "黑色";
bm.price = 400000f;
bm.run();
bm.stop();
Car bc = new Car();
bc.name = "奔驰";
bc.color = "白色";
bc.price = 5000000f;
bc.run();
bc.stop();
}
}
/*
发现类
汽车类:
[访问权限修饰符][修饰符] class 类名{
}
*/
public class Car {
/*
成员变量 类的属性
修饰符 类型 变量名 = [值]
*/
//public final String name;
//static String name;
String name;
String color;
float price;
/*
成员方法 类的行为(动词)
访问权限修饰符 返回值类/void 方法名(参数类型 参数名){
[return 值]
}
*/
//行驶
public void run(){
System.out.println("汽车行驶");
}
//刹车
public void stop(){
System.out.println("汽车刹车");
}
}
类中的变量
从数据类型角度分:
基本类型变量:byte int short long float double char boolean
引用类型变量:类 数组 接口等
按照位置来划分:
成员变量:直接被类所包含的变量
成员变量的数据类型可以为基本类型,也可以为引用类型
可以对成员变量进行初始化的赋值(不建议),如果不初始化,在创建对象时,可以调用构造方法使用默认值赋值
成员变量可以被类中的方法,构造方法,特定类的语句块进行访问
成员变量生命周期:变量什么时候生(对象创建),什么时候死(对象被回收时)
局部变量:在方法(成员方法,构造方法)中或者在代码块中包含的
局部变量在使用之前必需进行显示的初始化赋值
局部变量的生命周期:变量什么时候生(方法被调用时),什么时候死(方法运行结束 出栈)
类中的方法
成员方法:[非static修饰]被对象调用,完成对象的功能(行为),定义在类中
修饰符 返回值类型 方法名 ( 参数列表) {
方法体语句;
[return 返回值]
}
构造方法:用来初始化创建出来的对象.例如为对象中的属性进行赋值
方法名与类名相同,没有返回值,不需要void修饰
每一个类中至少有一个默认无参的构造方法,每次创建对象时至少调用一个.如果显示的定义一个构造方法,默认的就失效了.
方法重载:在一个类中,有多个方法的名称相同.
方法的区分:通过参数区分:参数个数不同,类型,顺序.
方法的重载与方法返回值类型无关
普通的成员方法的可以构成方法重载
//无参数构造方法
public Car(){
System.out.println("无参的构造方法");
}
//有参的构造方法
public Car(String n,String c){
name = n;
color = c;
System.out.println("有参的构造方法,String n,String c");
}
public Car(String n,float f){
name = n;
price = f;
System.out.println("有参的构造方法,String n,float f");
}
public Car(float f,String n){
name = n;
price = f;
System.out.println("有参的构造方法,String n,float f");
}
public Car(String n,String c,float f){
name = n;
color = c;
price = f;
System.out.println("有参的构造方法,String n,String c,float f");
}
对象与引用
java中的数据类型:
基本类型:byte short int long…简单类型
引用类型:除了基本类型都是引用类型,用类作为类型的都是引用类型,数组int a[]也是引用类型 也称为复合类型/复杂类型
为什么叫引用类型?
引用类型变量并不是持有对象本身,知识拥有对象的地址,通过地址间接访问对象.
//创建对象
Car car = new Car();
//对Car car = new Car();的解释
/*右边的“new Car()”,是以Car类为模板,调用Car类的构造函数,在堆空间里创建一个Car类对象。
左边的“Car car”创建了一个Car类型引用变量。所谓Car类的引用,就是以后可以用来指向Car 对象的对象引用。
”=”操作符使对象引用指向刚创建的那个Car对象。 我们可以把这条语句拆成两部分: Car car; car= new Car(); 这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。
*/
引用类型
数组,接口,类
他的值是对象在空间中的地址,具体对的对象存在堆中
值传递与引用传递
public class Test2 {
public static void main(String[] args) {
Dog xh = new Dog();
xh.name = "小黑";
Test2 t = new Test2();
t.test(xh);
System.out.println("xh=" +xh.name);//旺财
}
//引用类型传递时并不是将对象本身传递,只是将对象引用地址,这样形参发生变化,实参也会发生变化,因为两个指向的是同一个对象
public void test(Dog dog){
System.out.println("dog1=" +dog.name);//小黑
dog.name = "旺财";
System.out.println("dog2=" +dog.name);//旺财
}
}
static关键字
概念
static被称为静态,可以用来修饰成员变量,类的属性,方法,代码块,内部类.
static修饰的成员的特点
随着类的加载而加载
优先于对象存在
修饰的成员,被所有的类所共享
可以不创建对象,直接被类所调用
static属性:静态属性是类的所有对象共享的,即不管创建了多少个对象,静态属性在内存中只有一个.
public class Chinese{
//非静态属性
String name ;//姓名
//静态属性
static String country;//国家
}
static方法可以使用对象调用,也可以直接用类名调用,建议用类名直接调用.
在static方法内部只能访问类的static属性,不能访问类的非static属性,static属 性先加载。
public class Monimaipiao {
private static int ticket = 11;
public static void sellticket(){
ticket = ticket - 1;
System.out.println("卖票的静态方法!!!");
}
public static void main(String[] args) {
Monimaipiao.sellticket();
}
}
public class TestStaticMethod {
String name;//非静态的是在创建对象时加载
static int num = 10;
/**
* static修饰的方法随着类的加载而加载,static方法属于类,
* 但也可以被对象调用,建议使用类名static方法中不能使用非静态方变量,
* 因为静态的内容是先加载.
*/
public static void test() {
//System.out.println(name);//不能使用非静态的.
System.out.println(num);
}
//非静态的成员方法中,可以使用静态的成员变量
public void test1() {
System.out.println(num);
}
public static void main(String[] args) {
TestStaticMethod.test();
TestStaticMethod t = new TestStaticMethod();
t.test1();
}
}
代码块
代码块在类中声明,类似一个没有名称的方法体(代码块),代码分实例块和静态块
//实例快:每次创建对象时自动调用执行
{
//任何符合语法的java代码
}
//静态块:类加载时自动调用执行,仅一次,与是否创建对象无关
static{
//任何符合语法的java代码
}
/*代码块定义在类中,没有名称,分为实例代码块和静态代码块
实例块在创建对象时调用,每创建一次对象调用一次
静态代码块在类被加载时被调用,只执行一次.
类被加载时:第一次创建对象,实用类中的静态变量,静态方法
*/
public class Student {
public final static int n = 10;
/*
成员变量
*/
static int num;
static String name;
static String country = "中国";
//代码块定义在类中,没有名称,分为实例代码块和静态代码块
//实例块在创建对象时调用,每创建一次对象调用一次
{
System.out.println("实例代码块1!!!");
}
{
System.out.println("实例代码块2!!!");
}
//静态代码块在类被加载时被调用,只执行一次.
//类被加载时:第一次创建对象,实用类中的静态变量,静态方法
static {
System.out.println("静态代码块1!!!");
}
static {
System.out.println("静态代码块2!!!");
}
public Student(){
System.out.println("无参构造方法!!!");
}
public Student(int n, String na){
num = n;
name = na;
}
/*
成员方法
*/
public static void showInfo(){
System.out.println("学号"+num+"\t姓名"+name);
}
}
public class Test {
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
System.out.println(Student.country);
Student.showInfo();
}
}
类中元素的加载顺序
先加载静态的,静态的内容按照先后顺序进行加载
实例代码块
构造方法
包
包的概念
就是文件夹(从文件系统的角度来讲)
包的作用
按照不同的功能管理类 不同的模块 用户模块 部门模块 按照功能划分数据库连接 工具类…
避免类重名(每个包里面的类的功能、作用是不同的)
//从java角度来讲,包是类的路径,位置
//严格意义上的类名:全类名 = 包名 + 类的名称
import java.util.Date;//import 类的地址
//import java.sql.Date;
public class Test {
public static void main(String[] args) {
new Date(12);
new java.sql.Date(1000);
new Date();
}
}
控制访问权限(访问权限修饰符)
java.long包中的类在使用时不需要导入,使用其他包中的类时,需要使用import关键字导入.
访问权限修饰符
java语言有四个访问权限修饰符,权限从大到小依次为:
public:公共权限 修饰类,属性,方法.可以被任意类访问
protected:受保护的权限 修饰方法,属性 可以被同包类访问,如果不是同包类,必须是该类的子类才能访问
(defalut):同包权限 修饰类,方法,属性.只能被同包的类访问
private:私有权限 修饰方法,属性. 只能在本类中访问
包(package)的命名规范:
在包名中,可以使用.号来区分包的级别;包名一般情况下是小写
第一级 指该项目的类型,如com,org,gov等,
第二级 指项目所开发或者运行的公司名称,如:oracle,sun,huawei
等
第三级 指项目的名称,如:bcms,oa,erp,cms等
第四级 指项目模块的名称,如:bean,action,exception等
包可以更好得管理逻辑相关的类,可以控制不同包之间的访问权限
导入外部包的类,关键字"import".
面向对象的特征
封装
概念:将类的某些信息隐藏在类内部(权限问题),不允许外部程序直接访问, 而是通过该类提供特定的方法来实现对隐藏信息的操作和访问 。
优点:1.只能通过规定方法访问
2.隐藏类的实现细节
3.方便加入控制语句
4.方便修改实现
public class Person {
private String name;
private int age;
private static Person person = null;
public void SetName(String n) {
if (n != null || n.length() < 10) {
name = n;
}
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public void SetAge(int a) {
if (age >= 0 && age < 120) {
age = a;
}
}
/*
单例模式:在一个引用程序中,只能创建一个对象
public Person(){
}
public static Person getPerson(){
if (person!=null) {
person = new Person();
}
return person;
}*/
}
public class TestPerson {
public static void main(String[] args) {
Person p1 = new Person();
p1.SetName("asdfgh");
p1.SetAge(18);
System.out.println(p1.getName());
System.out.println(p1.getAge());
}
}
继承
概念:继承是面向对象程序设计不可缺少的设计思想,是实现代码可重用的根基,是提高代码可扩展性的主要途径。
继承是从已有的类中派生出新的类,新的类能吸收已有类的属性和行为,并能扩展新的能力。
在JAVA中使用extends关键字来表示继承关系。
JAVA支持多继承,单继承使JAVA的继承关系很简单,一个类只能有一个直接父类。
继承之后子类可以调用父类的所有非私有属性和非私有方法.
优点: 提高代码的复用性
继承使用场景
Student Dog Car Pseron
Dog 继承 Car
Car 继承 Dog
Dog 继承 Animal
Student 继承 Person
Teacher 继承 Person
继承是面向对象程序设计思想,提高代码的重用性,可扩展性
/*
设计一个动物类 父类 基类
当一个类没有显示的继承其他类的时候,此时这个类默认继承Object
Object类是java中所有类的基类(父类 超类)
*/
//public class Animal extends Object{
public class Animal{
private String name;
private int age;
public Animal(){
super();
System.out.println("Animal无参构造");
}
void eat(){
System.out.println("动物吃东西");
}
public void sleep(){
System.out.println("动物睡觉");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/*
设计Dog类
狗是动物 继承Animal 拥有父类中行为属性(非私有的)
java中的继承:一个类只能直接继承一个父类
Dog extends Animal 显示的继承 extends Object
*/
public class Dog extends Animal{
private String type;
//无参构造
public Dog(){
super();
System.out.println("Dog无参构造");
}
//有参构造
public Dog(String type){
super();
this.type=type;
System.out.println("Dog有参构造");
}
public void play(){
System.out.println("1111");
System.out.println(super.getName()+"狗会玩");
}
//构造方法,静态方法不能被重写, 属性也不存在重写,
//当父类中实现方式(代码) 不能满足子类中的需求,可以在子类中将父类中的方法重写(方法覆盖 覆写)
@Override//java中的注解标签 说明 此方法是从父类中重写过来的 在编译期间就会对语法进行校验
void eat() {
System.out.println("ssssss");//子类自己的实现方式
System.out.println("ssssss");
//super.eat();//调用父类的实现
super.sleep();
System.out.println("ssssss");
System.out.println("ssssss");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public class XiaoTianQuan extends Dog{
public XiaoTianQuan(){
// super();//super() 表示调用父类的构造方法
// super("牧羊犬");//调用父类的构造方法 默认调用(默认存在)
//如果使用super()显示的调用,则必须方法构造方法的第一行
System.out.println("XiaoTianQuan无参构造");
}
public void fly(){
System.out.println("哮天犬会飞");
}
}
public class Test {
public static void main(String[] args) {
Dog wc = new Dog();
wc.sleep();
wc.eat();
wc.setName("旺财");
wc.setAge(5);
System.out.println(wc.getName());
System.out.println(wc.getAge());
wc.setType("牧羊犬");
wc.play();
System.out.println(wc.getType());
wc.hashCode();
System.out.println("============================");
XiaoTianQuan xtq = new XiaoTianQuan();
xtq.hashCode();//Object
xtq.setName("哮天犬");//Animal
xtq.setAge(500);
xtq.play();//Dog
xtq.fly();//自己
}
}
public class Test1 {
public static void main(String[] args) {
/*
构造方法作用:初始化类的成员
*/
XiaoTianQuan xtq = new XiaoTianQuan();
// xtq.eat();
/*
当创建一个子类对象时,会在子类的构造方法中调用父类的构造方法,先去初始化父类.
默认会在构造方法的第一行使用super()调用
如果显示的使用使用super()调用,也必须在第一行,
可以使用super()传参,调用指定的构造方法
*/
}
}
public class Test2 {
public static void main(String[] args) {
Dog wc = new Dog();
wc.setName("旺财");
wc.play();
wc.eat(); //此时 wc 调用的是Dog类中重写的eat()
wc.sleep();
}
}
多态
概念:同一种事物,在不同时刻表现不同的状态
存在的三个必要条件:
1.要有继承(包括接口的实现)(前提条件)
2.要有重写(前提条件)
3.父类引用指向子类对象
Object obj = new Car();
obj = new Dog();
obj = new Cat();
多态环境下的调用
1.成员方法:编译看左边,运行看右边
2.静态方法:编译和运行都看左边
3.成员变量:编译和运行都看等号左边
方法参数具有多态性的好处:提高代码的扩展性
转型的作用:1.向上转型:提高程序的扩展型.
2.向下转型:为了使用子类中的特有方法.
this关键字
this关键字代表自身类的对象(this表示对象)
使用this关键字可以应用成员变量
使用this关键字可以引用成员方法
注意:this关键字必须放在非静态的方法里面
public void SetName(String name) {
if (name != null || name.length() < 10) {
//this表示当前正在操作的对象
this.name = name;
}
}
public void SetAge(int age) {
if (age >= 0 && age < 120) {
this.age = age;
}
}
在一个类的方法或构造方法内部,可以使用“this.成员变量名”这样的 格式来引用成员变量名,常常用来区分同名的成员变量和局部变量。
public class Student {
public final static int n = 10;
/*成员变量*/
int num;
String name;
public Student(){
}
public Student(int n,String na){
this.num = n;
this.name = na;
}
/*成员方法*/
public void showInfo(){
System.out.println("学号"+num+"\t姓名"+name);
}
}
单例模式
/*
设计模式:前人总结出解决某一类问题的方法
单例模式:在整个应用程序的运行过程中只创建一个对象
*/
public class WindowDemo {
static WindowDemo windowDemo=null;
//构造方法私有化
private WindowDemo(){
}
/*
向外界提供的获得对象的方法
*/
public static WindowDemo getWindowDemo(){
//控制只生成一个对象
if (windowDemo ==null){
windowDemo = new WindowDemo();
}
return windowDemo;
}
}
抽象类
/*
如果一个类中没有包含足够的信息(抽象方法)来描绘一个具体的对象,这样的类就是抽象 类。
抽象类中可以没有抽象方法,有抽象方法必定是抽象类
一般用在体系结构的顶层用来进行功能的定义声明
*/
public abstract class Animal {
int num;
/*
抽象类可以拥有构造方法,但是不能创建对象
*/
public Animal(){
System.out.println("Animal无参构造");
}
/*
*抽象方法:只有方法声明, 没有方法体,也就是没有具体的实现
*/
public abstract void eat();//在比较顶级的类中就可以定义一个方法即可
public void sleeep(){
System.out.println("动物睡觉");
}
}
/*
一个类如果继承了抽象类
要么重写抽象类中所有的抽象方法
要么将该类也定义为抽象类
*/
//public abstract class Dog extends Animal {
public class Dog extends Animal {
public Dog(){
super();
}
@Override
public void eat() {
System.out.println("狗吃东西");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
System.out.println(dog.num);
dog.eat();
dog.sleeep();
}
}
final关键字
用于声明属性,方法和类
属性:定义就必须直接赋值或者在构造方法中进行赋值,并且后期都不能修改.
方法:子类里不可以重写.
类:不能被定义为抽象类或者接口,不可以被继承.
final属性赋值
1.在声明时同时赋值,往往与static一起使用
2.声明时不赋值,必须在构造方法中注意赋值
总的原则:保证创建每一个对象的时候,final属性的值是确定的.
public class FinalDemo {
/*
总体原则:
保证创建每一个对象的 时候,final属性的值是确定的。
*/
//final属性赋值:在声明时同时赋值,往往与 static一起使用。
static final int PI = 3;
//在声明时如果不赋值,则必须在构造方法中进行赋值
final int num;
public FinalDemo(int n) {
num = n;
}
public static void main(String[] args) {
FinalDemo finalDemo1 = new FinalDemo(10);
FinalDemo finalDemo2 = new FinalDemo(20);
System.out.println(finalDemo1.num);
System.out.println(finalDemo2.num);
}
}
public class Demo extends FinalDemo {
public Demo(int n) {
super(n);
}
}
接口
接口的定义和使用
定义:使用interface关键字用来声明一个接口
[访问修饰符] interface 接口名称 [extends 其他的接口名1,….其他的接口名n]
{
// 声明常量 抽象方法 静态方法 默认方法
}
使用:类使用implements关键字实现接口。在类声明中,Implements关 键字放在class声明后面。
[访问修饰符] class 类名 implements 接口名1,接口名2……{
}
结合继承
[访问修饰符] class 类名 extends 父类名 implements 接口名1,接口名2……{
}
public class MyInterfaceImpl implements MyInerface{
public static void main(String[] args) {
MyInterfaceImpl myInterface = new MyInterfaceImpl();
myInterface.eat();
myInterface.sleep();
myInterface.test1();
}
@Override
public void eat(){
System.out.println("eat!!!!!!!");
}
@Override
public void test1() {
System.out.println("test1!!!!!");
}
@Override
public void sleep(){
System.out.println("sleep!!!!!!");
}
}
public interface MyInerface {
int NUM = 10;
//public abstract void eat();
void eat();
void sleep();
//默认方法
default void test1(){
System.out.println("默认方法!!!");
}
//静态方法
static void test2(){
System.out.println("静态方法!!!");
}
}
接口的特性
接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
接口中方法可以是抽象的,静态的,默认的。
接口中声明的属性默认为 public static final 的;
接口不是被类继承了,而是要被类实现。
接口不能实例化对象(无构造方法),但可以声明对象的引用。(多态性)
多个类可以实现同一个接口。
一个类可以实现多个接口,但只能继承一个类。
与继承关系类似,接口与实现类之间存在多态性。
一个接口能继承其它多个接口。
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明 为抽象的类。