zoukankan      html  css  js  c++  java
  • 面向对象练习

    竟然复活了!

    不做过多的文字阐述,想看网上一坨一坨的,这里我弄个小练习穿插贯彻一下.

    一个关于学校成绩查询管理的小软件;

    能用到这个软件的人大致分三类:教师,学生,管理员. 那么就是最基本的单位,我们通过类可以构造出:张老师,李老师,同学甲,同学乙,管理孙等.所以我们定义类是为了以后

    构造具体的实体用.(比如我们要构造个张老师就要通过构造函数: Teacher 张老师=new Tearcher();  Tearcher就是们定义的类)

    那么张老师就是个具体的实体了,身为一个老师他要有他自己的属性,如: 姓名,性别,身高,体重,年龄,教龄,教职工号,所教专业等; 那么这些属性我们就可以继承类的属性,因为

    所有老师都具备这些属性只是属性的值不同,那么我们就要给类赋予一定的属性.按照不同的需要我们要把这些属性封装起来,好处呢就是增加类的重用性安全性.

    我们还是沿用之前<SQL初级第三课(上)>的学生成绩表;

    首先,封装几个类,(建议类和类的函数建在一个文件夹里面)

    using System;                                      
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace obj
    {
        public class Student
        {
    
            private string _Sno;
    
            public string Sno
            {
                get { return _Sno; }
                set { _Sno = value; }
            }
            private string _Sname;
    
            public string Sname
            {
                get { return _Sname; }
                set { _Sname = value; }
            }
            private string _Ssex;
    
            public string Ssex
            {
                get { return _Ssex; }
                set { _Ssex = value; }
            }
            private String _Sbirthday;
    
            public String Sbirthday
            {
                get { return _Sbirthday; }
                set { _Sbirthday = value; }
            }
            private string _Class;
    
            public string Class
            {
                get { return _Class; }
                set { _Class = value; }
            }
        }
    }

    这样就建了一个学生类,并对类的属性进行了一个简单的封装 首先是 写入 private _Sno 然后在字段上右键>重构>封装字段 系统自动生成

      public string Sno
            {
                get { return _Sno; }
                set { _Sno = value; }
            }

    我们调用的都是public的数据,但是值却储存在private里面(比如说银行,我们存钱或取钱不能去金库(private _Sno)进行操作而是去柜台找出纳(public string Sno)

    这里面的get, set就是存钱,取钱)这里用的是VS2012当然其他版本也可以自己手写 get;set;简写也是可以的.如上我们封装其他三个类Teacher,Course,还有一个

    综合类Type

    ________________________________________________依然华丽的分割线_____________________________________________________

    这里做个登录页面,要求用comboBox选择用户类型,输入账户和密码,然后根据用户类型进入不同页面,如学生 进入学生页面只能查询该学生的信息.

    --->

    一般思路:根据comboBox的选项去查相应数据库(如码A),帐号就是学生表的Sno主键,然后建一个返回bool值的函数把输入的帐号和密码做比对(如码B),成功就登录相应的学生界面并根据主键查询出学生姓名和成绩并显示(如码C)

    码A:
    public class LoginDA { SqlConnection conn; SqlCommand cmd; public LoginDA() { conn=new SqlConnection("server=.;database=aaaaa;user=sa;pwd=123"); cmd=conn.CreateCommand(); } public bool checkStu(Login user) { bool isok = false; cmd.CommandText = "select * from Slogin where username=@username and pasword=@pasword"; cmd.Parameters.Clear(); cmd.Parameters.Add("@username", user.Username); cmd.Parameters.Add("@pasword", user.Pasword); conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) { isok = true; } else cmd.Dispose(); conn.Close(); return isok; }
      
    码B:
    private void button1_Click(object sender, EventArgs e)//登录 { string username =textBox1.Text ; string pasword=textBox2.Text; string fenlei=comboBox1.Text; Login u = new Login(); u.Username = username; u.Pasword = pasword; if (fenlei=="萌萌哒") { bool res=new LoginDA().checkStu(u); if (res == true) { Form3 stu = new Form3(username); this.Owner=stu; this.Visible = false; stu.Show(); } else { MessageBox.Show("臭不要脸"); } }
    码C:
    public partial class Form3 : Form { private string id; public Form3(string username) { id = username; InitializeComponent(); } string a = null; private void button1_Click(object sender, EventArgs e) { List<type> list = new StudentDA().Sser(id); bindListView(list); } private void Form3_Load(object sender, EventArgs e) { label2.Text = label(id); } private string label(string id) { string str="server=.;database=aaaaa; user=sa; pwd=123"; SqlConnection conn = new SqlConnection(str); SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = "select sname from student where sno=@sno"; cmd.Parameters.Clear(); cmd.Parameters.Add("@sno", id); conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); if (dr.Read()) { a = dr["Sname"].ToString(); } return a ; } public void bindListView(List<type> list) //绑定listView { listView1.Columns.Clear(); listView1.Columns.Add("学生编号"); listView1.Columns.Add("学生姓名"); listView1.Columns.Add("课程编号"); listView1.Columns.Add("课程名称"); listView1.Columns.Add("教师姓名"); listView1.Columns.Add("分数"); listView1.Items.Clear(); if (list != null) { for (int i = 0; i < list.Count; i++) { listView1.Items.Add(list[i].Sno); listView1.Items[i].SubItems.Add(list[i].Sname); listView1.Items[i].SubItems.Add(list[i].Cno); listView1.Items[i].SubItems.Add(list[i].Cname); listView1.Items[i].SubItems.Add(list[i].Tname); listView1.Items[i].SubItems.Add(list[i].Degree); } } }
     
    码D:
    public List<type> Sser(string id) { List<type> data = null; cmd.CommandText = "select Student.sno,sname,Course.Cno,cname,tname,degree from Score join Student on student.sno=score.sno join course on course.Cno=score.Cno join teacher on teacher.tno=course.tno where Student.sno=@Sno"; cmd.Parameters.Clear(); cmd.Parameters.Add("@Sno",id); conn.Open(); SqlDataReader dr=cmd.ExecuteReader(); if(dr.HasRows) { data=new List<type>(); while(dr.Read()) { type d = new type(); d.Sno=dr["Sno"].ToString(); d.Sname=dr["Sname"].ToString(); d.Cno=dr["Cno"].ToString(); d.Cname=dr["Cname"].ToString(); d.Tname=dr["Tname"].ToString(); d.Degree=dr["Degree"].ToString(); data.Add(d); } } cmd.Dispose(); conn.Close(); return data; }
    
    
    
     

    构造函数传值,将Form1中的一个数据(username)传入Form3中,在Form3中建立同类型的一个变量(id)来接收从Form1中传来的(username)(如码B,C中大红色)

    显示的区域.相当于我们建立一个带参数的函数Form3(string username).

    类和类的方法,public class LoginDA 我们建立了一个LoginDA的类在它里面有个 public LoginDA与类名一致的特殊函数类函数,它没有返回值但可以有参数

    可以不写(如码A中绿色显示)

    连接数据库操作,码A就是一段连接数据库将输入参数跟数据库相应参数进行比对,然后返回比对结果,如果要用sqlConnection 请引用using System.Data.SqlClient;

    List<>泛型集合,<>里面是一个类,要填写一个类名,表示有好多此类型的对象;

    连接数据库查询, 码D中 此段函数应写在如码A类中带有连接数据库代码的类中,cmd.CommandText=""是指令,""里输入SQL指令,根据不同的需要些增删改查

    SqlDataReader dr=cmd.ExecuteReader(); dr是一个光标,代表的是整个查询结果.

    listView添加数据,个人感觉比较难用,需要见一个绑定函数(如码C 的bindListView(List<type> list)),因为需要一个List<>的参数所以查询完数据库接受的时时候

    就要接收或转换成List<>形式,数据接口必须一致.

    ________________________________________________依然华丽的分割线________________________________________________________

    教师登录页面,实现对所有学生成绩的查询,修改,增添,查询.

    教师职责是对学生的成绩进行发布,所以教师的功能着重于学生成绩的修改.

    至于学生信息的添加,修改,删除等操作,我们留给管理员.

    -->

    这里如果我只想看成绩我可以用一个dataGridView来查询,拖入一个dataGridView,它接收一个List<>泛型集合的数据源,

       public List<type> Search()
        {
            List<type> data = null;
            cmd.CommandText = "select Student.sno,sname,Course.Cno,cname,tname,degree from Score join  Student on student.sno=score.sno join  course  on course.Cno=score.Cno join teacher  on teacher.tno=course.tno";
            cmd.Parameters.Clear();
            conn.Open();
            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.HasRows)
            {
                data = new List<type>();
                while (dr.Read())
                {
                    type a = new type();
                    a.Sno = dr["Sno"].ToString();
                    a.Sname = dr["Sname"].ToString();
                    a.Cno = dr["Cno"].ToString();
                    a.Cname = dr["Cname"].ToString();
                    a.Tname = dr["Tname"].ToString();
                    a.Degree = dr["Degree"].ToString();
                    data.Add(a);
                }
            }
            cmd.Dispose();
            conn.Close();
            return data;
        }
            private void Form9_Load(object sender, EventArgs e)
            {
                List<type> list = new StudentDA().Search();
                if (list != null)
                {
                    dataGridView1.AutoGenerateColumns = false;
                    dataGridView1.DataSource = list;
                }
            }

    dataGridView接收到了数据源我们就要对其进行匹配设置,首先选择 FullRowSelect

    再添加列

    这里的 DataPropertyName是List<>类里面的列名或者叫做属性,需要显示哪些就绑定哪些.

    但是List<>类里面其他的属性就没有了吗? 并不是只是没有显示,并非没有传进去.

    查询选中学生的任课教师,这个在Type类型里面有,那么我们可以直接让他显示出来

     type stu = (type)dataGridView1.SelectedRows[0].DataBoundItem;
                MessageBox.Show(stu.Tname.ToString());

    如果Type类里面没有的我们也可以获取其有的信息,进行进一步查询.

    提示所选学生的性别,

      private void button2_Click(object sender, EventArgs e)
            {
                string xb = dataGridView1.SelectedRows[0].Cells[1].Value.ToString();
            
                string a = new StudentDA().Sex(xb);
                MessageBox.Show(a);
            }

    ________________________________________________依然华丽的分割线________________________________________________________

    修改学生成绩等信息,

     public void Update(type data)
            {
               // cmd.CommandText = "update student set sname=@Sname where student.sno=@Sno and score.sno=@Sno update score set degree=@Degree where course.cno=@Cno and  student.sno=@sno update course set cname=@Cname where student.sno=@Sno and course.cno=@Cno update teacher set tname=@tname where course.cno=@cno ";
                cmd.CommandText = "update student set sname=@Sname where sno=@Sno;update score set degree=@Degree where cno=@Cno and sno=@Sno;update course set cname=@Cname where cno=@Cno;update teacher set tname=@Tname where tno =(select tno from course where cno=@Cno)";
                cmd.Parameters.Add("@Sno", data.Sno);
                cmd.Parameters.Add("@Sname", data.Sname);
                cmd.Parameters.Add("@Cno", data.Cno);
                cmd.Parameters.Add("@Cname", data.Cname);
                cmd.Parameters.Add("@Tname", data.Tname);
                cmd.Parameters.Add("@Degree", data.Degree);
                conn.Open();
                cmd.ExecuteNonQuery();
                conn.Close();
            }

      private void button4_Click(object sender, EventArgs e)
                {
                    if (listView1.SelectedItems.Count > 0)
                    {
                        string id = listView1.SelectedItems[0].Text.ToString();
                        string od = listView1.SelectedItems[0].SubItems[2].Text.ToString();
                        Form5 f = new Form5(id,od);
                        f.Show();                    
                    }
                }
    public partial class Form5 : Form     
        {
            private string Id;
            private string Od;
            public Form5(string id,string od)
            {
                InitializeComponent();
                Id=id;
                Od = od;
            }
            private void Form5_Load(object sender, EventArgs e)
            {
                type b = new StudentDA().Ss(Id,Od);
                if (b != null)
                {
                    textBox1.Text = b.Sno;
                    textBox2.Text = b.Sname;
                    textBox3.Text = b.Cno;
                    textBox4.Text = b.Cname;
                    textBox5.Text = b.Tname;
                    textBox6.Text = b.Degree;
                }
            }
        private void button1_Click(object sender, EventArgs e)
            {
                MessageBoxButtons m = MessageBoxButtons.OKCancel;
                DialogResult dr = MessageBox.Show("确定要修改吗?", "取消", m);
                if (dr == DialogResult.OK)
                {
                    type data = new type();
                  
                        data.Sno = textBox1.Text;
                        data.Sname = textBox2.Text;
                        data.Cno = textBox3.Text;
                        data.Cname = textBox4.Text;
                        data.Tname = textBox5.Text;
                        data.Degree = textBox6.Text;               
                        new StudentDA().Update(data);
                        MessageBox.Show("修改成功");
                        Form4.o = 1;
                        this.Close();    
                }
            }
        }
    }

    因为一个学生的成绩要有两个条件决定的,1个是学生的学号来确定是谁,2是这个学生的课程号来确定是哪一门可,因为一个学生可以考多门课,所以我们就要传入两个数据

    构造函数传值(如大红色区域),但是问题又来了,我们一旦修改,如何将新修改的数据立即显示出来呢?

    这里我定义了一个全局变量,一个公共的静态int类 ,  public static int o = 0; 这个o可以被在此命名空间下的任何类调用,然后在显示页面Form4里面加入timer来完成查询,当点击修改o=1触发查询,如图

    public static int o = 0;


    private void timer1_Tick(object sender, EventArgs e) { if (o == 0) { } else if (o == 1) { List<type> cx = new StudentDA().Search(); bindListView(cx); } o = 0; }

    ________________________________________________依然华丽的分割线________________________________________________________

    管理员嘛,自己看看吧

  • 相关阅读:
    C语言温习杂记
    C语言变量类型与内存管理
    解析搜狗新闻语料库
    关于clang, scan-build, 和clang test
    Clang checker类总结
    让你的checker出现在clang的checker list中
    Clang安装配置解释
    Operators 操作
    cumulative_distribution累积分布
    SVM
  • 原文地址:https://www.cnblogs.com/18553325o9o/p/4655041.html
Copyright © 2011-2022 走看看